你的位置:首页 > 软件开发 > ASP.net > 实践基于Task的异步模式

实践基于Task的异步模式

发布时间:2015-10-22 00:00:17
Await返回该系列目录《基于Task的异步模式--全面介绍》 在API级别,实现没有阻塞的等待的方法是提供callback(回调函数)。对于Tasks来说,这是通过像ContinueWith的方法实现的。基于语言的异步支持通过允许在正常控制流内部等待异 ...

Await

返回该系列目录《基于Task的异步模式--全面介绍》


 

     在API级别,实现没有阻塞的等待的方法是提供callback(回调函数)。对于Tasks来说,这是通过像ContinueWith的方法实现的。基于语言的异步支持通过允许在正常控制流内部等待异步操作隐藏callbacks,具有和编译器生成的代码相同的API级别的支持。

    在.Net 4.5,C#直接异步地支持等待的Task和Task<TResult>,在C#中使用"await"关键字。如果等待一个Task,那么await表达式是void类型。如果等待一个Task<TResult>,那么await表达式是TResult类型。await表达式必须出现在返回类型是void,Task,Task<TResult>的异步方法体内。

   在幕后,await功能通过在该Task上的一个continuation(后续操作)安装了一个callback(回调函数)。此回调将恢复暂停的异步方法。当该异步方法恢复时,如果等待的异步操作成功地完成,并且它是一个Task<TResult>,那它就返回一个TResult。如果等待的Task或者Task<TResult>以Canceled状态结束,那么会引发OperationCanceledException。如果等待的Task或者Task<TResult>以Faulted状态结束,那么会引发造成它失败的异常。对于一个Task来说,可能由于多个异常造成失败,在这种情况下,这些异常只有一个会传递。然而,该Task的Exception属性会返回一个包含所有错误的AggregateException。

如果一个同步上下文和执行在挂起状态的异步方法相关联(如SynchronizationContext.Current是非空的),那么异步方法的恢复会通过使用该下上文的Post方法发生在相同的同步上下文上。否则,它会依赖当前在挂起点的System.Threading.Tasks.TaskScheduler是什么(针对.Netget='_blank'>线程池,一般这个默认是TaskScheduler.Default)。它取决于该TaskScheduler是否允许恢复在等待异步操作完成的地方或者强制恢复被调度的地方执行。默认的调度一般会允许后续操作在等待的操作完成的线程上执行。

当调用的时候,异步方法同步地执行方法体,直到遇到在还没有完成的等待的实例上的第一个await表达式,此时控制权返回给调用者。如果该异步方法没有返回void,那么就会返回Task或Task<TResult>表示正在进行的计算。在一个非void的异步方法中,如果遇到了return语句或者到达了方法体的末尾,那么该task会以RanToCompletion的最终状态完成。如果一个未处理的异常造成控制权离开了异步方法体,该任务会以Faulted状态结束(如果异常是OperationCanceledException,任务会以Canceled状态结束)。结果或异常最终以这种方式发布。

Yield 和 ConfigureAwait

一些成员对异步方法的执行提供了更多的控制。Task类提供了一个Yield方法,可以使用它把一个屈服点(yield point)引入异步方法。

public class Task : …

{

public static YieldAwaitable Yield();

}

这个等价于异步地推送(post)或调度回到当前的上下文。

Task.Run(async delegate

{

for(int i=0; i<1000000; i++)

{

await Task.Yield(); // fork the continuation into a separate work item

...

}

原标题:实践基于Task的异步模式

关键词:异步

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。