基于任务的异步编程模式(TAP)
异步编程是C#5.0的一个重要改进,提供两个关键字:async和await。使用异步编程,方法的调用是在后台运行(通常在线程或任务的帮助下),但不会阻塞调用线程。异步模式分为3种:异步模式、基于事件的异步模式和基于任务的异步模式(TAP)。TAP是利用关键字async和await实现的,本文将讲解TAP模式。async和await关键字只是编译器的功能。编译器最终会用Task类创建代码。
1、创建任务
建立一个同步方法Greeting,该方法在等待一段时间后,返回一个字符串。
private string Greeting(int delay, string name)
{
System.Threading.Thread.Sleep(delay);
return string.Format("Hello, {0}.", name);
}
定义一个方法GreetingAsync,可以使方法异步化,其传入的参数不做强制要求。基于任务的异步模式指定,并返回一个任务。注意,该方法返回的是Task<string>,定义了一个返回字符串的任务,与同步方法返回值一致。
private Task<string> GreetingAsync(string name, int delay = )
{
return Task.Run<string>(() =>
{
return Greeting(delay, name);
});
}
2、调用异步方法
可以使用await关键字调用返回任务的异步方法GreetingAsync。但是,使用await关键字的方法必须要用async关键字修饰符声明。在GreetingAsync方法完成前,被async关键字修饰的方法内await关键字后面的代码不会继续执行。但是,启动被async关键字修饰的方法的线程可以被重用,而没有被阻塞。
public async void CallerWithAsync()
{
string result = await GreetingAsync("Nigel", );
Console.WriteLine(result);
}
注意:async修饰符修饰只能用于返回Task或void的方法。不能作为程序的入口点,即Main方法不能使用async修饰符。await修饰符只能用于返回Task的方法。
3、延续任务
GreetingAsync方法返回一个Task<string>对象。该对象包含任务创建的信息,并保存到任务完成。Task类的ContinueWith方法可在任务完成后继续调用的代码。
public void CallsWithContinuationTask()
{
Task<string> task = GreetingAsync("Stephanie", );
task.ContinueWith(t =>
{
Console.WriteLine(t.Result);
});
}
实际上,编译器会把await关键字后的所有代码放进ContinueWith方法内。不论是await关键字的方法还是任务的ContinueWith方法,在方法的不同生命阶段使用了不同的线程。都是当await关键字的方法或任务执行完毕后,再由另一个线程去执行await关键字后面的代码,或给当前线程添加新的任务去执行相关代码。
在具有UI的应用程序中,应用程序的窗体的控件不允许跨线程访问,需要使用控件的InvokeRequired属性和Invoke方法,将访问UI的方法代码块以委托的形式传递给控件的Invoke,但是在执行前需要判断控件的InvokeRequired。在使用async和await关键字,当await完成后,不需要做任何处理,就可以放访问UI线程(实际上是将控制权又交给了UI线程)。
4、使用多个异步方法
4.1、按顺序调用多个异步方法
使用await关键字可以调用每个异步方法。如果一个异步方法依赖于另一个异步方法,将会起到很大作用。但当异步方法之间没有相互依赖的时候,不使用await关键字将更快返回结果。
public async void MultipleAsyncMethods()
{
DateTime start = DateTime.Now;
string result1 = await GreetingAsync("Jack",);//先执行完它
string result2 = await GreetingAsync("Tim",);//再执行它
//输出结果
Console.WriteLine("Finished both methods: MultipleAsyncMethods.\nResult 1: {0}, Result 2: {1}", result1, result2);
Console.WriteLine("Use time: {0}", (DateTime.Now - start).TotalMilliseconds);
}
4.2、使用组合器
如果任务之间并不依赖于另一个任务,每个异步方法都不需要使用await,而是把每个异步方法的返回结果赋值给Task变量,使用组合器让这些任务并行运行。当组合器内的所有任务都完成后,才会执行后面的代码。
public async void MultipleAsyncMethodsWithCombinators1()
{
DateTime start = DateTime.Now;
Task<string> t1= GreetingAsync("Jack", );
Task<string> t2= GreetingAsync("Tim", );
await Task.WhenAll(t1, t2);
//输出结果
Console.WriteLine("Finished both methods: MultipleAsyncMethodsWithCombinators1.\nResult 1: {0}, Result 2: {1}", t1.Result, t2.Result);
Console.WriteLine("Use time: {0}", (DateTime.Now - start).TotalMilliseconds);
}
如果所有任务类型都返回相同的类型,则可用该类型的数组作为await返回的结果
public async void MultipleAsyncMethodsWithCombinators2()
{
DateTime start = DateTime.Now;
Task<string> t1 = GreetingAsync("Jack", );
Task<string> t2 = GreetingAsync("Tim", );
string[] results= await Task.WhenAll(t1, t2);
//输出结果
Console.WriteLine("Finished both methods: MultipleAsyncMethodsWithCombinators2.\nResult 1: {0}, Result 2: {1}", results[], results[]);
Console.WriteLine("Use time: {0}", (DateTime.Now - start).TotalMilliseconds);
}
5、异步方法的异常处理
如果调用异步方法,但是没有等待,那么调用异步方法的线程中使用传统的try/catch块是不能捕获到异步方法中的异常。因为在异步方法执行出现异常之前,已经执行完毕。
如何捕获异常见《基于任务的异步编程模式(TAP)的错误处理》。
基于任务的异步编程模式(TAP)的更多相关文章
- 基于任务的异步编程模式(TAP)的错误处理
		
在前面讲到了<基于任务的异步编程模式(TAP)>,但是如果调用异步方法,没有等待,那么调用异步方法的线程中使用传统的try/catch块是不能捕获到异步方法中的异常.因为在异步方法执行出现 ...
 - 二、基于事件的异步编程模式(EAP)
		
一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式--APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题--不支持对异步操作的取消和没有提供对进 ...
 - 基于任务的异步编程模式,Task-based Asynchronous Pattern
		
术语: APM 异步编程模型,Asynchronous Programming Model,其中异步操作由一对 Begin/End 方法(如 FileStream.BeginRea ...
 - 异步编程(二)基于事件的异步编程模式 (EAP)
		
一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式——APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进 ...
 - .Net Core自实现CLR异步编程模式(Asynchronous programming patterns)
		
最近在看一个线程框架,对.Net的异步编程模型很感兴趣,所以在这里实现CLR定义的异步编程模型,在CLR里有三种异步模式如下,如果不了解的可以详细看MSDN 文档Asynchronous progra ...
 - C#中的异步编程模式
		
异步编程模型(APM) 基于事件的异步编程模式 基于任务的异步模式 Async Await编程 关于C#,可以看看Learning Hard的博客
 - .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)
		
本文内容 异步编程类型 异步编程模型(APM) 参考资料 首先澄清,异步编程模式(Asynchronous Programming Patterns)与异步编程模型(Asynchronous Prog ...
 - [.net 多线程]异步编程模式
		
.NET中的异步编程 - EAP/APM 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异 ...
 - .NET异步编程模式(一)
		
.NET 提供了三种异步编程模型 TAP - task-based asynchronous pattern APM - asynchronous programming model EAP - ev ...
 
随机推荐
- 2016女生赛 HDU 5710 Digit-Sum(数学,思维题)
			
Digit-Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total S ...
 - Pycharm快速复制当前行到下一行Ctrl+D
			
Pycharm快速复制当前行到下一行Ctrl+D
 - DoDataExchange函数,UpdateData(TRUE)和UpdateData(FALSE)的区别
			
MFC控件(暂时为Edit控件)与数据的绑定,变量值可以在界面和后台之间传递. 我们在DoDataExchange(CDataExchange* pDX) 函数里,实现了MFC控件和变量的绑定. 若 ...
 - Ehcache入门介绍一
			
EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. 特性有: 1. 快速轻量 Ehcache的线程机制是为大型高并发系统设 ...
 - windows下配置非安装版的MySQL5.6
			
Installing MySQL on Microsoft Windows Using a noinstall Zip Archive,在Windows上使用非安装压缩包安装MySQL.安装步骤如下: ...
 - 分布式爬虫搭建系列 之四---scrapy分布式框架
			
带录入SAFCDS
 - Valid timeZone Values(转)
			
https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/timezone.html Valid time ...
 - Perl 变量:标量变量、数组变量、哈希变量和变量上下文
			
一.Perl 变量变量是存储在内存中的数据,创建一个变量即会在内存上开辟一个空间.解释器会根据变量的类型来决定其在内存中的存储空间,因此你可以为变量分配不同的数据类型,如整型.浮点型.字符串等.上一章 ...
 - CSS 内容生成
			
原文地址:http://www.zhangxinxu.com/wordpress/?p=739 一.哗啦哗啦的简介 zxx://这里“哗啦哗啦”的作用是为了渲染一种氛围.content属性早在CSS2 ...
 - mongo_1 新手之路
			
mongodb 进入.在bin目录下 至于安装各位自己查资料吧 .不废话了 直接上图.这种表示已经成功进入mongo 本人mongo 数据库存放地址.如有需要可以清空可以自己删除. 接下来就是 ...