百科问答小站 logo
百科问答小站 font logo



如何正确理解.NET 4.5和C# 5.0中的async/await异步编程模式? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

await修饰的方法返回的是一个Task,而这个Task其实就是一个异步句柄,如果我来取名字的话多半就叫做IAsyncHandler。

一个IAsyncHandler你可以想象成是这么一个东西:

       public interface IAsyncHandler {   Register( Action continuation ); }      

这是伪代码,事实上不存在这么个东西。


注册一个回调方法在异步操作完成后继续,所以事实上这段代码的原理像是这样的:

       private async void btnDoStuff_Click(object sender, RoutedEventArgs e) {   btnDoStuff.IsEnabled = false;   lblStatus.Content = "Doing Stuff";    var handler = Task.Delay(4000) as IAsyncHandler   handler.Register( () =>   {     lblStatus.Content = "Not Doing Anything";     btnDoStuff.IsEnabled = true;   } ); }     

当然上面全是伪代码,但是如果你能看懂这段代码在干什么,那么async基本就可以懂了,剩下的只是一些实现细节上的问题。


通常情况下,Task.Delay会立即返回一个Task对象,这个Task对象会在指定时间之后被标记为Completed,而被标记Completed就会立即开一个线程来进行延续的操作。

但是这里有个问题就是你这个方法是写在UI线程里面的,控件的事件会被UI线程触发,而UI线程上有个SynchronizationContext对象,这个对象的存在就会使得系统在异步回调的时候去捕获源线程。在原来的线程(UI线程)去执行延续的任务。

而我们知道WinForm里面有个方法叫做Control.Invoke,可以把一个方法封送到UI线程去执行,而上面的工作和这个方法底层的原理其实是一样的,所以,其实这段代码用传统的思维来理解的话像是这样:

       private async void btnDoStuff_Click(object sender, RoutedEventArgs e) {   btnDoStuff.IsEnabled = false;   lblStatus.Content = "Doing Stuff";    Action continuation = () =>   {     lblStatus.Content = "Not Doing Anything";     btnDoStuff.IsEnabled = true;   };    Thread.Start( () =>   {     Thread.Sleep( 4000 );     Control.Invoke( continuation );   } ); }     



  

相关话题

  .NET 平台中有很多 BS 框架,能介绍一下他们之间的关系和实用价值吗? 
  2019 年了,C# 发展得怎么样了? 
  为什么说try catch 隐藏了bug,C# try catch什么时候用? 
  为什么没有新的支持底层达到类似C++这种程度,而易用性达到C#的语言出现? 
  如何看待 .NET Native,真能达到 C++ 的性能、C# 的生产效率吗? 
  大三下学期了,比较熟悉C#但哪都看到JAVA薪资和发展都比.net好,想转学JAVA,还来得及吗? 
  c# 双核多线程并行计算 Parallel是不是最优方案? 
  用 C# 写个方法解析简单的 JSON 字符串有哪些思路? 
  C#中的String.Format()这两种写法那个更好? 
  很多人都说 C# 语法怎么优雅,仅仅是因为 C# 的关键字多吗? 

前一个讨论
太空到达地球的「光」用了多久是如何计算的?
下一个讨论
jpeg图片在网页中引用时为什么只能写成jpg?





© 2025-05-05 - tinynew.org. All Rights Reserved.
© 2025-05-05 - tinynew.org. 保留所有权利