博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c#进阶(7)—— 异步编程基础(async 和 await 关键字)
阅读量:5227 次
发布时间:2019-06-14

本文共 4143 字,大约阅读时间需要 13 分钟。

  async 和 await 关键字只是编译器功能,编译器会用Task类创建代码。
返 回值是一个Task,这种返回新线程的方法虽然可以提高系统的响应能力,但是多线程取值会给编码带来不便,所以新出的关键字await用于阻塞当前线程并 获取目标线程的返回值,在方法体中使用await关键字后要求将方法声明为async用来表示该方法是异步的,并且返回值必须为void或者将返回者封装 在一个Task中
1、创建任务
  同步方法Greeting ,该方法等待一段时间后,返回一个字符串,通过GetHashCode 查看当前线程ID
代码如下:
static string Greeting(string name)        {            Task.Delay(3000).Wait();            int j  = Task.CurrentId.GetHashCode();            Console.WriteLine("name" + name);            int i =Thread.CurrentThread.GetHashCode();            Thread.Sleep(3000);            Console.WriteLine("Task 的线程HASHCODE是: " + j);            Console.WriteLine("Thread 的线程HASHCODE是" + i);            Console.ReadLine();            Thread.Sleep(3000);            return $"Hello,{name}";        }
定义方法GreetingAsync,可以使方法异步化,基于任务的异步模式指定,在异步方法名后加上Async后缀,并返回一个任务,异步方法GreetingAsync 和 同步方法Greeting具有相同的输入参数,但是异步方法返回的是Task<string>,Task<string> 定义了一个返回字符串的任务。代码如下所示:
///         /// 异步调用方法        ///         ///         /// 
static Task
GreetingAsync(string name) { return Task.Run
(()=> { return Greeting(name); }); }

2、调用异步方法

可以使用await 关键字来调用返回任务的异步方法GreetingAsync,使用await 关键字需要用async修饰符声明的方法,在GreetingAsync方法完成前,该方法内其他代码不会继续执行,但是启动
CallerWithAsync方法的线程可以被重用,该线程没有阻塞。
代码如下所示:
class Program    {        static void Main(string[] args)        {            CallerWithAsync();        }        ///         /// 调用异步方法        ///         private async static void CallerWithAsync()        {            string result = await GreetingAsync("chenk");            Console.WriteLine(result);        }

 3、延时任务

GreetingAsync 方法返回一个Task<string> 对象,对象包含任务创建的信息,并保存到任务完成,Task类的ContinueWith 方法定义了任何完成后就调用的代码,指派给ContinueWith方法的委托,将已完成的任务作为参数传入,使用Result属性,可以访问任务返回的结果。代码如下:
///         /// 延续任务        ///         private static void CallerWithContinuationTask()        {            Task
t1 = GreetingAsync("chenk"); //编译器把await 关键字后的代码放进ContinueWith 方法的代码块转换await关键字 t1.ContinueWith(t => { string result = t.Result; Console.WriteLine("CallerWithContinuationTask 线程Id :" + Thread.CurrentThread.GetHashCode() + "; result 的值为:" + result); Console.ReadLine(); }); }
4、同步上下文
验证方法中使用的线程,可以点击‘启动’——在‘调试’中选择‘线程’,即可查看当前异步程序运行的线程数及位置,以CallerWithContinuationTask为例,可以看到一个线程为主线程、一个线程在调用GreetingAsync方法、一个线程在执行ContinueWith方法内的代码堆。截图如下:

 

5、使用多个异步方法
5.1 按顺序调用多个异步方法
使用await 关键字可以调用每个异步方法,如果一个异步方法依赖于另一个异步方法的结果,await关键字就非常有用。
本例中,GreetingAsync 异步方法的第二次调用完全独立于第一次调用的结果,如果每个异步方法都不使用await,那么整个MultipleAsyncMethods异步方法将更快返回结果。代码如下:
private async static void MutipleAsyncMethods()        {            string s1 = await GreetingAsync("chenk");            string s2 = await GreetingAsync("zhangf");            Console.WriteLine("Finished both methods \nResult 1:" + s1 + "\nResult 2:" + s2);            Console.ReadLine();        }

  5.2 使用组合器

如果异步方法不依赖于其他异步方法,则每个异步方法都不使用await ,而是把每个异步方法的返回结果赋值给Task变量,就会运行的更快,GreetingAsync方法返回Task<string>。这些方法现在可以并行执行了。
组合器可以帮助实现这一点,一个组合器可以接受多个同一类型的参数,并返回同一类型的值,多个同一类型的参数被组合成一个参数传递,Task组合器接受多个Task对象作为参数,并返回一个Task。
示例代码采用Task.WhenAll组合器方法,它可以等待,直到两个任务都完成。代码如下:
///         /// 组合器 WhenAll        ///         private async static void MultipleAsyncMethodWithCombinatoral()        {            Task
t1 = GreetingAsync("chenk"); Task
t2 = GreetingAsync("zhangf"); //WhenAll 组合器,从WhenAll方法返回的Task,是在所有传入方法的任务都完成了才会返回Task。 //WhenAny 组合器,是在其中一个传入方法的任务完成了就会返回Task。 await Task.WhenAll(t1, t2); } ///
/// 组合器WhenAll 重载,如果所有的任务返回相同的类型,那么该类型的数组可用于await返回的结果 /// private async static void MultipleAsyncMethodWithCombinatoral2() { Task
t1 = GreetingAsync("chenk"); Task
t2 = GreetingAsync("zhangf"); string[] result = await Task.WhenAll(t1, t2); }

 

 

 

转载于:https://www.cnblogs.com/cklovefan/p/8051606.html

你可能感兴趣的文章
iOS开发UI篇—UITabBarController简单介绍
查看>>
MAC OX 配置JDK环境变量
查看>>
数据结构与算法自学系列之动态规划(一)
查看>>
《团队-----吃货之家------项目总结》
查看>>
在Android迷你广告上添加浮动的关闭按钮
查看>>
python之HTMLParser解析HTML文档
查看>>
Attach、Detach和DeleteObject
查看>>
nodejs实现Websocket的数据接收发送
查看>>
Asp.Net Core 基于QuartzNet任务管理系统(这是一篇用来水的随笔)
查看>>
SpringMVC处理静态资源
查看>>
Weblogic漏洞修复记录
查看>>
《设计模式之禅》学习笔记(十四)
查看>>
linux中sudo命令的使用
查看>>
二、React中的更新
查看>>
Codeforces Round #499 (Div. 2) D. Rocket题解
查看>>
吃一垫长一智
查看>>
串口(USART)通信-串口通讯协议简介
查看>>
如何统计Visual Studio Code项目的代码行数
查看>>
第二章——信息的表示和处理
查看>>
[转]《ASP.NET 本质论》HttpApplication的处理管道
查看>>