标签:com sleep open 同步 bsp 常用事件 处理程序 exe div
Task异步编程中,可以实现在等待耗时任务的同时,执行不依赖于该耗时任务结果的其他同步任务,提高效率。
1、Task异步编程方法签名及返回值:
a) 签名有async 修饰符
b) 方法名以 Async 结尾(良好的编码习惯)
根据约定,将“Async”追加到具有 async 修饰符的方法名称。如果某一约定中的事件、基类或接口协定建议其他名称,则可以忽略此约定。例如,你不应重命名常用事件处理程序,例如 btnOpen_Click。
c) 返回类型如下:
d) 方法通常包含至少一个 await 表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成,方法才能继续。 同时,将方法挂起,并且控制权将返回到方法的调用方。
举例如下:
private static async Task<int> OperateAsync()
2、 举例分析:
class Program { static void Main(string[] args) { DoClickAsync(); Console.ReadKey(); } private static async void DoClickAsync() { Task<int> result = OperateAsync(); int resultValue = await result; Console.WriteLine("耗时操作结果" + resultValue.ToString()); } private static async Task<int> OperateAsync() { HttpClient client = new HttpClient(); //执行异步方法 GetStringAsync Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com"); //由于下面的非异步方法不依赖上面异步方法结果,因此可以先执行,假设在这里执行一些非异步的操作 DoIndependentWork(); //等待操作挂起方法 OperateAsync,直到 getStringTask 完成,OperateAsync 方法才会继续执行 //同时,控制将返回到 OperateAsync 方法的调用方,直到 getStringTask 完成后,将在这里恢复控制。 //然后从 getStringTask 拿到字符串结果 string urlContents = await getStringTask; //返回字符串的长度(int 类型) return urlContents.Length; } private static void DoIndependentWork() { for (int i = 0; i < 5; i++) { Console.WriteLine("主线程执行内容" + i); Thread.Sleep(1000); } } }
3、步骤分析:
【备注】
(1)如果 GetStringAsync(即 getStringTask)在 OperateAsync 等待前完成,则控制权会保留在 OperateAsync 中。 如果异步调用过程 (getStringTask) 已完成,并且OperateAsync不必等待最终结果,则挂起然后返回到 OperateAsync,但这会造成成本的浪费。
(2)在调用方内部(DoClickAsync),处理模式将继续。在等待结果前,调用方可以开展不依赖于OperateAsync结果的其他工作,否则就需等待片刻。DoClickAsync等待 OperateAsync,而 OperateAsync 等待 GetStringAsync。
4、同步行为和异步行为差异:
5、详谈返回类型:
在.NET 中,异步方法通常返回 Task 或 Task<TResult>。在异步方法中,await运算符应用于通过调用另一个异步方法返回的任务。
1、如果方法包含指定类型 TResult 的操作数的return语句,则将 Task<TResult> 指定为返回类型。
2、如果方法不含任何 return 语句或包含不返回操作数的 return 语句,则将Task用作返回类型。
【备注】
每个返回的任务表示正在进行的工作。任务可封装有关异步进程状态的信息,如果未成功,则最后会封装来自进程的最终结果或进程引发的异常。
3、异步方法还可以是具有void返回类型。该返回类型主要用于定义需要void返回类型的事件处理程序。异步事件处理程序通常用作异步程序的起始点。无法等待具有void返回类型的异步方法,并且一个void返回值的调用方无法捕获该方法引发的任何异常。
下面的示例演示如何声明并调用可返回 Task 或 Task<TResult> 的方法。
static void Main(string[] args) { DoMethodAsync(); Console.ReadKey(); } private static async void DoMethodAsync() { //调用Method1Async /*方式一*/ Task<Guid> t1 = Method1Async(); Guid guid1 = t1.Result; Console.WriteLine("调用Method1Async方式一操作结果" + guid1.ToString()); /*方式二*/ Guid guid2 = await Method1Async(); Console.WriteLine("调用Method1Async方式二操作结果" + guid2.ToString()); //调用Method2Async /*方式一*/ Task t2 = Method2Async(); await t2; /*方式二*/ await Method2Async(); } //返回Task<TResult>类型 static async Task<Guid> Method1Async() //Task<Guid> { Console.WriteLine("调用Method1Async"); var result = Guid.NewGuid(); await Task.Delay(10000); //这里返回一个 Guid 的类型 return result; } //返回Task类型 static async Task Method2Async() //Task { Console.WriteLine("调用Method2Async"); //Do... await Task.Delay(10000); //Do... //这里没有 return 语句 }
6、总结:
1、标记的异步方法(通过使用 async 修饰符)可以使用 await 来指定悬挂点。await 运算符通知编译器,异步方法只有直到等待的异步过程完成才能继续通过该点。同时,控制权将返回至异步方法的调用方。
2、异步方法通常包含 await 运算符的一个或多个匹配项,但缺少 await 表达式不会导致编译器错误。如果异步方法未使用 await 运算符标记悬挂点,则该方法将作为同步方法执行,不管异步修饰符(async)如何。编译器将为此类方法发布一个警告。
7、参考:
http://www.cnblogs.com/liqingwen/p/5922573.html
标签:com sleep open 同步 bsp 常用事件 处理程序 exe div
原文地址:http://www.cnblogs.com/SimplePerson/p/6103839.html