C#中的异步和多线程

简介:

 

1.异步与多线程

异步是当调用者发出一个调用请求之后,调用者不用等待其结果的返回,可以继续进行其他操作,操作结果在请求完成之后返回,通过回调或者其他机制通知调用者。

实现异步可以采用多线程技术,或者交给另外的进程来处理。

异步是一种行为模式,可以用于很多地方。多线程可以用来实现异步行为模式。

和异步相对应的概念应该是同步,同步需要等待执行成功之后才能返回。

异步与多线程,从辩证关系上看,异步和多线程并不是一个同等关系,异步是目的,多线程只是实现异步的一种手段。异步还可以用消息,或者是委托到其他进程来实现。

多个线程之间可以是同步的,也可以是异步的。

I/O操作多用异步的方式,耗时处理的操作多用多线程。

2.线程安全

在WinForm开发中,常见的一个错误就是“线程中操作无效:从不是创建控件XXX的线程访问它。”

这个错误在WinForm开发中是很常见的一种错误。

下面的这段代码就会发生这样的错误。

 
  1. private void button4_Click(object sender, EventArgs e) 
  2.       { 
  3.           var task = new Task(() => 
  4.           { 
  5.               this.lblResult.Text = DateTime.Now.ToLongTimeString(); 
  6.           }); 
  7.           task.Start(); 
  8.       } 

通常发生在使用多线程的时候,在线程中想要更新界面上的一些控件的信息。因为这些控件是在主线程中创建的,所以在非主线程的其他线程中,对这些控件进行更新操作,会报出这个错误提示。

通过下面的方式来修正这个错误。

 

 
  1. private void button4_Click(object sender, EventArgs e) 
  2.       { 
  3.           var task = new Task(() => 
  4.           { 
  5.               this.lblResult.Invoke(new Action (() => { 
  6.                   this.lblResult.Text = DateTime.Now.ToLongTimeString(); 
  7.               }));  
  8.           }); 
  9.           task.Start(); 
  10.       } 

不是在其非主线程中直接更新空间,而是定义一个委托,在非主线程中执行这个委托,在委托中更新控件。来实现在非主线程中更新控件的属性。

3.C#中的async和await实现异步

有时候为了不阻塞主线程,也就是通常说的不要阻塞UI,或者UI界面不要“死了”,我们需要使用多线程的技术,把一些计算或者是处理任务交给新的线程,待有结果之后再显示给主线程。

3.1.在async和await之前

在async和await之前,我们使用异步编程,begininvoke,然后再callback中处理显示结果。

 

 
  1. private void button2_Click(object sender, EventArgs e) 
  2.       { 
  3.           this.lblResult.Text = "starting to ..."
  4.           var compute = new Func<intstring>(i => 
  5.           { 
  6.               long result = 1; 
  7.  
  8.               for (int n = 0; n <= i; n++) 
  9.               { 
  10.                   result += 1; 
  11.               } 
  12.                
  13.               return result.ToString(); 
  14.           }); 
  15.  
  16.           compute.BeginInvoke(int.MaxValue / 2, new AsyncCallback(ar => 
  17.           { 
  18.               #region  
  19.               //异步是通过多线程来实现的,lblResult是在主线程中创建的控件,异步是在另外一个线程执行 
  20.               //所以不能修改主线程中创建的控件  
  21.               //this.lblResult.Text = compute.EndInvoke(ar); 
  22.               #endregion 
  23.  
  24.               this.lblResult.Invoke(new MethodInvoker(() => 
  25.                   this.lblResult.Text = compute.EndInvoke(ar))); 
  26.           } 
  27.           ), new object()); 
  28.       } 

3.2.有了async和await之后

async和await是在.NET4.5中引入的异步编程关键字,给我们编写异步代码带来了极大的便利,极大地减少了代码的编写,使我们更加集中于具体业务的实现。

async和await也是一种语法糖。

相当于是同步编程的方式实现异步编程的效果。

 
  1. public long DoSomething(int n) 
  2.    { 
  3.        long result = 1
  4.  
  5.        for (int i = 0; i <= n; i++) 
  6.        { 
  7.            result += 1; 
  8.        } 
  9.  
  10.        return result; 
  11.    } 
  12. private async void button3_Click(object sender, EventArgs e) 
  13.    { 
  14.        this.lblResult.Text = "staring to ..."
  15.        var value = await DoSomethingAsync(int.MaxValue / 2); 
  16.        this.lblResult.Text = value.ToString(); 
  17.    } 
  18.    private Task<long> DoSomethingAsync(int n) 
  19.    { 
  20.        return Task.Run<long>(() => DoSomething(n)); 
  21.    } 

 

参考文献

1.C# 5.0功能之Async一瞥

2.Asynchronous Programming with Async and Await (C# and Visual Basic)

3.关于C#中async/await中的异常处理(上)

3.关于C#中async/await中的异常处理(下)

4..NET 基于Task的异步编程模型

5.同步/异步与阻塞/非阻塞的区别

 

 




本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1033189,如需转载请自行联系原作者

目录
相关文章
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
1月前
|
C#
C#学习相关系列之多线程---ConfigureAwait的用法
C#学习相关系列之多线程---ConfigureAwait的用法
|
1月前
|
C#
C#学习相关系列之多线程---TaskCompletionSource用法(八)
C#学习相关系列之多线程---TaskCompletionSource用法(八)
|
1月前
|
Java C#
C#学习系列相关之多线程(五)----线程池ThreadPool用法
C#学习系列相关之多线程(五)----线程池ThreadPool用法
|
26天前
|
Python
Python学习之路 02 之分支结构
Python学习之路 02 之分支结构
47 0
Python学习之路 02 之分支结构
|
26天前
|
Java Python 开发者
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
74 2
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
|
21天前
|
JavaScript 前端开发
JS 单线程还是多线程,如何显示异步操作
JS 单线程还是多线程,如何显示异步操作
22 2
|
1月前
|
C#
C#学习系列相关之多线程(二)----Thread类介绍
C#学习系列相关之多线程(二)----Thread类介绍
|
1月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法

热门文章

最新文章