开班接触
分类:计算机编程

走进异步编制程序的世界 - 发轫接触 async/await

 

[C#] 开端接触 async/await 异步编制程序,

  那是上学异步编程的入门篇。

  涉及 C# 5.0 引进的 async/await,但在调整台出口示例时平时会选择 C# 6.0 的 $"" 来拼接字符串,也就是string.Format() 方法。

 

初始接触 async/await 异步编制程序

目录

  • What's 异步?
  • async/await 结构
  • What’s 异步方法?

 

  那是学习异步编制程序的入门篇。

 

一、What's 异步?

     运行程序时,系统会在内部存款和储蓄器中开创二个新的历程。进度是构成运路程序能源的集结。

     在进度之中,有可以称作线程的基础对象,它意味着的是真的的实践顺序。系统会在 Main 方法的首先行语句就起来线程的执行。

 

     线程:

     ①暗中同意境况,一个进程只含有三个线程,从程序的初始到实行完结;

     ②线程能够派生自别的线程,所以八个经过能够分包分化景色的多个线程,来施行顺序的两样部分;

     ③一个历程中的八个线程,将分享该进度的财富;

     ④体系为Computer试行所设计的单元是线程,而非进度。

 

     平日的话我们写的调节台程序都只利用了二个线程,从第一条语句按顺序实践到最后一条。但在比非常多的情事下,这种轻巧的模子会在性质或顾客体验上倒霉。

     比方:服务器要同一时间管理来自三个顾客端程序的伸手,又要等待数据库和别的设备的响应,那将严重影响属性。程序不该将时刻浪费在响应上,而要在伺机的同不经常候奉行其余职务!

     以后我们开始步向异步编制程序。在异步程序中,代码无需固守编写时的依次实行。那个时候大家须要用到 C# 5.0 引入的 async/await 来创设异步方法。

 

     大家先看一下不用异步的演示:

 1     class Program
 2     {
 3         //创建计时器
 4         private static readonly Stopwatch Watch = new Stopwatch();
 5 
 6         private static void Main(string[] args)
 7         {
 8             //启动计时器
 9             Watch.Start();
10 
11             const string url1 = "http://www.cnblogs.com/";
12             const string url2 = "http://www.cnblogs.com/liqingwen/";
13 
14             //两次调用 CountCharacters 方法(下载某网站内容,并统计字符的个数)
15             var result1 = CountCharacters(1, url1);
16             var result2 = CountCharacters(2, url2);
17 
18             //三次调用 ExtraOperation 方法(主要是通过拼接字符串达到耗时操作)
19             for (var i = 0; i < 3; i  )
20             {
21                 ExtraOperation(i   1);
22             }
23 
24             //控制台输出
25             Console.WriteLine($"{url1} 的字符个数:{result1}");
26             Console.WriteLine($"{url2} 的字符个数:{result2}");
27 
28             Console.Read();
29         }
30 
31         /// <summary>
32         /// 统计字符个数
33         /// </summary>
34         /// <param name="id"></param>
35         /// <param name="address"></param>
36         /// <returns></returns>
37         private static int CountCharacters(int id, string address)
38         {
39             var wc = new WebClient();
40             Console.WriteLine($"开始调用 id = {id}:{Watch.ElapsedMilliseconds} ms");
41 
42             var result = wc.DownloadString(address);
43             Console.WriteLine($"调用完成 id = {id}:{Watch.ElapsedMilliseconds} ms");
44 
45             return result.Length;
46         }
47 
48         /// <summary>
49         /// 额外操作
50         /// </summary>
51         /// <param name="id"></param>
52         private static void ExtraOperation(int id)
53         {
54             //这里是通过拼接字符串进行一些相对耗时的操作
55             var s = "";
56 
57             for (var i = 0; i < 6000; i  )
58             {
59                 s  = i;
60             }
61 
62             Console.WriteLine($"id = {id} 的 ExtraOperation 方法完成:{Watch.ElapsedMilliseconds} ms");
63         }
64     }

图片 1

     图1-1 运转的作用图,以皮秒(ms)为单位

 

  【备注】平日的话,直接拼接字符串是风华正茂种相比较耗质量的手腕,假设对字符串拼接有质量供给的话应该利用 StringBuilder。

  【注意】每一趟运转的结果恐怕差别。不管哪次调节和测量检验,绝当先一半时刻都浪费前四次调用(CountCharacters 方法),即在伺机网址的响应上。

 

图片 2

  图1-2 依据实行结果所画的大运轴

 

     有人曾幻想着这么进步性能的方法:在调用 A 方法时,不等它实践完,直接试行 B 方法,然后等 A 方法实践到位再管理。

     C# 的 async/await 就能够允许大家如此弄。

图片 3图片 4

 1     class Program
 2     {
 3         //创建计时器
 4         private static readonly Stopwatch Watch = new Stopwatch();
 5 
 6         private static void Main(string[] args)
 7         {
 8             //启动计时器
 9             Watch.Start();
10 
11             const string url1 = "http://www.cnblogs.com/";
12             const string url2 = "http://www.cnblogs.com/liqingwen/";
13 
14             //两次调用 CountCharactersAsync 方法(异步下载某网站内容,并统计字符的个数)
15             Task<int> t1 = CountCharactersAsync(1, url1);
16             Task<int> t2 = CountCharactersAsync(2, url2);
17 
18             //三次调用 ExtraOperation 方法(主要是通过拼接字符串达到耗时操作)
19             for (var i = 0; i < 3; i  )
20             {
21                 ExtraOperation(i   1);
22             }
23 
24             //控制台输出
25             Console.WriteLine($"{url1} 的字符个数:{t1.Result}");
26             Console.WriteLine($"{url2} 的字符个数:{t2.Result}");
27 
28             Console.Read();
29         }
30 
31         /// <summary>
32         /// 统计字符个数
33         /// </summary>
34         /// <param name="id"></param>
35         /// <param name="address"></param>
36         /// <returns></returns>
37         private static async Task<int> CountCharactersAsync(int id, string address)
38         {
39             var wc = new WebClient();
40             Console.WriteLine($"开始调用 id = {id}:{Watch.ElapsedMilliseconds} ms");
41 
42             var result = await wc.DownloadStringTaskAsync(address);
43             Console.WriteLine($"调用完成 id = {id}:{Watch.ElapsedMilliseconds} ms");
44 
45             return result.Length;
46         }
47 
48         /// <summary>
49         /// 额外操作
50         /// </summary>
51         /// <param name="id"></param>
52         private static void ExtraOperation(int id)
53         {
54             //这里是通过拼接字符串进行一些相对耗时的操作
55             var s = "";
56 
57             for (var i = 0; i < 6000; i  )
58             {
59                 s  = i;
60             }
61 
62             Console.WriteLine($"id = {id} 的 ExtraOperation 方法完成:{Watch.ElapsedMilliseconds} ms");
63         }
64     }

那是修正后的代码

图片 5

 图1-3 改过后的实施结果图

图片 6

图1-4 根据参与异步后的实施结果画的光阴轴。

 

  我们入眼时间轴发掘,新版代码比旧版快了重重(由于网络波动的原因,很恐怕会师世耗时比以前长的状态)。那是由于 ExtraOperation 方法的多次调用是在 CountCharactersAsync 方法调用时等待响应的进程中进行的。所有的事业都以在主线程中完成的,未有创建新的线程。

 

  【退换深入分析】只改了几个细节的地点,直接开展代码的话只怕看不出来,改变如下:

   图片 7

 图1-5

图片 8

  图1-6

 

  ①从 Main 方法推行到 CountCharactersAsync(1, url1) 方法时,该方法会即刻重临,然后才会调用它里面包车型客车艺术开头下载内容。该措施重回的是一个Task<int> 类型的占位符对象,表示安排打开的干活。那一个占位符最后会重临 int 类型的值。

  ②如此就足以不要等 CountCharactersAsync(1, url1) 方法实行到位就足以三回九转拓宽下一步操作。到施行 CountCharactersAsync(2, url2)  方法时,跟 ① 同样重返 Task<int> 对象。

  ③然后,Main 方法继续实施叁遍 ExtraOperation 方法,同期三次 CountCharactersAsync 方法仍旧在反复工作 。

  ④t1.Result 和 t2.Result 是指从 CountCharactersAsync 方法调用的 Task<int> 对象取结果,要是还没结果的话,将阻塞,直有结果回到截至。

 

目录

  • What's 异步?

  • async/await 结构

  • What’s 异步方法?

 

二、async/await 结构

     先深入深入分析一下专门的学业名词:

     同步方法:八个前后相继调用有些方法,等到其实行到位之后才开展下一步操作。这也是私下认可的花样。

     异步方法:叁个程序调用某些方法,在管理完了从前就回去该办法。通过 async/await 我们就能够完毕那种类型的章程。

 

     async/await 结构可分为三有的:

     (1)调用方法:该办法调用异步方法,然后在异步方法奉行其任务的时候继续试行;

     (2)异步方法:该办法异步试行专门的职业,然后随时回去到调用方法;

     (3)await 表明式:用于异步方法内部,提出要求异步试行的任务。三个异步方法能够包含多个await 表明式(不设有 await 表明式的话 IDE 会发出警报)。

 

  以后大家来分析一下演示。

图片 9

  图2-1

 

一、What's 异步?

     运营程序时,系统会在内部存款和储蓄器中开创贰个新的进度。进度是构成运路程序能源的集合。      在进程之中,有堪称线程的基础对象,它意味着的是确实的进行顺序。系统会在 Main 方法的第生龙活虎行语句就从头线程的奉行。        线程:      (1)暗许景况,五个经过只包罗一个线程,从程序的牵头到实践实现;      (2)线程能够派生自此外线程,所以二个进度可以分包差别境况的多个线程,来执行顺序的两样部分;      (3)多少个历程中的多个线程,将分享该进程的财富;      (4)系统为计算机试行所设计的单元是线程,而非进度。        日常的话大家写的调节台程序都只利用了一个线程,从第一条语句按顺序试行到结尾一条。但在众多的景况下,这种简易的模型会在性质或客户体验上不佳。      比方:服务器要同时管理来自四个顾客端程序的央求,又要等待数据库和其他设备的响应。那将严重影响属性。程序不应有将时刻浪费在响应上,而要在等待的同一时间执行其它任务!      将来我们开端读书异步编制程序。在异步程序中,代码不供给依据编写时的相继实施。那时候大家须要用到 C# 5.0 引进的 async/await 来营造异步方法。        大家先看一下不用异步的演示:

 1     class Program
 2     {
 3         //创建计时器
 4         private static readonly Stopwatch Watch = new Stopwatch();
 5 
 6         private static void Main(string[] args)
 7         {
 8             //启动计时器
 9             Watch.Start();
10 
11             const string url1 = "http://www.cnblogs.com/";
12             const string url2 = "http://www.cnblogs.com/liqingwen/";
13 
14             //两次调用 CountCharacters 方法(下载某网站内容,并统计字符的个数)
15             var result1 = CountCharacters(1, url1);
16             var result2 = CountCharacters(2, url2);
17 
18             //三次调用 ExtraOperation 方法(主要是通过拼接字符串达到耗时操作)
19             for (var i = 0; i < 3; i  )
20             {
21                 ExtraOperation(i   1);
22             }
23 
24             //控制台输出
25             Console.WriteLine($"{url1} 的字符个数:{result1}");
26             Console.WriteLine($"{url2} 的字符个数:{result2}");
27 
28             Console.Read();
29         }
30 
31         /// <summary>
32         /// 统计字符个数
33         /// </summary>
34         /// <param name="id"></param>
35         /// <param name="address"></param>
36         /// <returns></returns>
37         private static int CountCharacters(int id, string address)
38         {
39             var wc = new WebClient();
40             Console.WriteLine($"开始调用 id = {id}:{Watch.ElapsedMilliseconds} ms");
41 
42             var result = wc.DownloadString(address);
43             Console.WriteLine($"调用完成 id = {id}:{Watch.ElapsedMilliseconds} ms");
44 
45             return result.Length;
46         }
47 
48         /// <summary>
49         /// 额外操作
50         /// </summary>
51         /// <param name="id"></param>
52         private static void ExtraOperation(int id)
53         {
54             //这里是通过拼接字符串进行一些相对耗时的操作
55             var s = "";
56 
57             for (var i = 0; i < 6000; i  )
58             {
59                 s  = i;
60             }
61 
62             Console.WriteLine($"id = {id} 的 ExtraOperation 方法完成:{Watch.ElapsedMilliseconds} ms");
63         }
64     }

【注意】每便运维的结果只怕两样。不管哪次调试,绝大部分光阴都浪费前一回调用(CountCharacters 方法),即在伺机网址的响应上。     图1-2 根据实行结果所画的日子轴

 

     有人曾幻想着这么提升品质的不二等秘书诀:在调用 A 方法时,不等它实行完,间接实践 B 方法,然后等 A 方法实行到位再管理。      C# 的 async/await 就能够允许大家如此弄。 图片 10 1 class Program 2 { 3 //成立沙漏 4 private static readonly Stopwatch Watch = new Stopwatch(); 5 6 private static void Main(string[] args) 7 { 8 //运维计时器 9 Watch.Start(); 10 11 const string url1 = ""; 12 const string url2 = ""; 13 14 //三次调用 CountCharactersAsync 方法(异步下载某网址内容,并总结字符的个数) 15 Task<int> t1 = CountCharactersAsync(1, url1); 16 Task<int> t2 = CountCharactersAsync(2, url2); 17 18 //三次调用 ExtraOperation 方法(首纵然通过拼接字符串达到耗费时间操作) 19 for (var i = 0; i < 3; i ) 20 { 21 ExtraOperation(i 1); 22 } 23 24 //调整台出口 25 Console.WriteLine($"{url1} 的字符个数:{t1.Result}"); 26 Console.WriteLine($"{url2} 的字符个数:{t2.Result}"); 27 28 Console.Read(); 29 } 30 31 /// <summary> 32 /// 计算字符个数 33 /// </summary> 34 /// <param name="id"></param> 35 /// <param name="address"></param> 36 /// <returns></returns> 37 private static async Task<int> CountCharactersAsync(int id, string address) 38 { 39 var wc = new WebClient(); 40 Console.WriteLine($"在此早前调用 id = {id}:{沃特ch.ElapsedMilliseconds} ms"); 41 42 var result = await wc.DownloadStringTaskAsync(address); 43 Console.WriteLine($"调用落成 id = {id}:{Watch.ElapsedMilliseconds} ms"); 44 45 return result.Length; 46 } 47 48 /// <summary> 49 /// 额外操作 50 /// </summary> 51 /// <param name="id"></param> 52 private static void ExtraOperation(int id) 53 { 54 //这里是透过拼接字符串实香港行政局地对峙耗费时间的操作 55 var s = ""; 56 57 for (var i = 0; i < 6000; i ) 58 { 59 s = i; 60 } 61 62 Console.WriteLine($"id = {id} 的 ExtraOperation 方法成功:{沃特ch.Elapsed米尔iseconds} ms"); 63 } 64 } 那是订正后的代码

 图1-3 纠正后的实践结果图

图1-4 依照插足异步后的施行结果画的岁月轴。

 

  我们观看时间轴开采,新版代码比旧版快了好多(由于网络波动的因由,很大概会产出耗费时间比此前长的事态)。那是出于 ExtraOperation 方法的数拾贰遍调用是在 CountCharactersAsync 方法调用时等待响应的历程中张开的。全数的办事都以在主线程中成就的,未有开立异的线程。     【改造解析】只改了多少个细节的地点,直接开展代码的话恐怕看不出来,改动如下:      图1-6

 

  ①从 Main 方法实行到 CountCharactersAsync(1, url1) 方法时,该方法会马上回到,然后才会调用它里面包车型客车法子开首下载内容。该方法再次回到的是八个Task<int> 类型的占位符对象,表示布置实行的职业。这几个占位符最后会回到 int 类型的值。

  ②那样就能够不必等 CountCharactersAsync(1, url1) 方法实施到位就能够一而再接二连三展开下一步操作。到施行 CountCharactersAsync(2, url2)  方法时,跟 ① 相同重临 Task<int> 对象。

  ③然后,Main 方法继续实施一回 ExtraOperation 方法,同期一回 CountCharactersAsync 方法照旧在持续专门的工作 。

  ④t1.Result 和 t2.Result 是指从 CountCharactersAsync 方法调用的 Task<int> 对象取结果,要是还从未结果的话,将封堵,直有结果再次回到结束。

 

 三、What’s 异步方法

     异步方法:在施行到位前及时回到调用方法,在调用方法继续试行的长河中实现义务。

     语法深入分析:

     (1)关键字:方法头使用 async 修饰。

     (2)供给:满含N(N>0) 个 await 表明式(不设有 await 表明式的话 IDE 会发出警示),表示要求异步试行的天职。

     (3)重临类型:只可以回去 3 种类型(void、Task 和 Task<T>)。Task 和 Task<T> 标志重回的靶子会在几天前成功专业,表示调用方法和异步方法能够继续实施。

     (4)参数:数量不限,但不能够应用 out 和 ref 关键字。

     (5)命名约定:方法后缀名应以 Async 结尾。

     (6)此外:无名氏方式和 Lambda 表达式也能够用作异步对象;async 是三个上下文关键字;关键字 async 必需在回到类型前。

 图片 11

图3-1 异步方法的简短结构图

 

二、async/await 结构

     先拆解解析一下专门的学业名词:      同步方法:一个程序调用某些方法,等到其实行到位之后才开展下一步操作。那也是暗中认可的款型。      异步方法:八个主次调用有个别方法,在管理完了以前就回来该方法。通过 async/await 我们就足以兑现那类别型的不二等秘书技。        async/await 结构可分为三局地:      (1)调用方法:该方式调用异步方法,然后在异步方法试行其职责的时候继续实施;      (2)异步方法:该办法异步执行职业,然后登时回去到调用方法;      (3)await 表明式:用于异步方法内部,建议要求异步施行的职分。一个异步方法能够分包八个await 表明式(不设有 await 表明式的话 IDE 会发出警示)。     以往大家来解析一下演示。   图2-1

 

小结

  1.分析了经过和线程的定义

  2.异步的简要用法

  3.async/await 结构体

  4.异步主意语法结构

 

 三、What’s 异步方法

     异步方法:在奉行到位前及时赶回调用方法,在调用方法继续奉行的进度中成就职责。      语法解析:      (1)关键字:方法头使用 async 修饰。      (2)供给:饱含 N(N>0) 个 await 表明式(不设有 await 表明式的话 IDE 会发出警报),表示必要异步实行的职务。      (3)重回类型:只可以回到 3 种档案的次序(void、Task 和 Task<T>)。Task 和 Task<T> 标志重返的靶子会在今后完成工作,表示调用方法和异步方法能够继续施行。      (4)参数:数量不限,但不可能选用 out 和 ref 关键字。      (5)命名约定:方法后缀名应以 Async 结尾。      (6)此外:无名格局和 Lambda 表达式也足以当做异步对象;async 是三个上下文关键字;关键字 async 必得在回去类型前。  图3-1 异步方法的总结结构图

 

传送门

  下篇:《[走进异步编制程序的社会风气 -

小结

  1.解析了经过和线程的定义

  2.异步的大约用法

  3.async/await 结构体

  4.异步主意语法结构

 


本文首联: --那是起头版本,待整合治理形成并核对后再重复公布到首页,望见谅!--

] 开始接触 async/await 异步编程, 起首接触 async/await 异步编程 序 那是学习异步编制程序的入门篇。 目录 What's 异步? async/await 结构 Whats 异步...

剖析异步方法(上)](

解析异步方法(下)](

  后篇:《走进异步编制程序的社会风气 - 在 GUI 中施行异步操作》

 


正文首联:

【参考】《Illustrated C# 2012》

本文由pc28.am发布于计算机编程,转载请注明出处:开班接触

上一篇:一些很酷的,获取本地磁盘信息 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • 一些很酷的,获取本地磁盘信息
    一些很酷的,获取本地磁盘信息
    直接上干货简单易懂 原作出处:http://www.codeproject.com/useritems/tips.asp?df=100 //磁盘监控(远程/本地) //需要引用System.Management.dll public class RemoteMonitoring { pri
  • 福寿康宁劳务端webSocket连接通信
    福寿康宁劳务端webSocket连接通信
    前言 近日socket通讯使用TCP、UDP协调,个中TCP公约相对来说相比较安全和谐!本文也是来说学TCP为主(恕在下学艺不精)。      上面是私人商品房精晓的
  • 编写翻译安装javascript,Centos系统一整合体安装
    编写翻译安装javascript,Centos系统一整合体安装
    3,解压安装,设置安装路线 tar zxvf Python-3.6.5.tgz mkdir /usr/local/python365 cd Python-3.6.5 ./configure --prefix=/usr/local/python365 make make install   解释: tar是解压tgz包 ./
  • 如何在手机上实现饼图图表
    如何在手机上实现饼图图表
    最前方的话:Smobiler是一个在VS意况中使用.Net语言来开采APP的开辟平台,也许比Xamarin更低价   生机勃勃、指标准样本式 咱俩要兑现上海教室中的效果,需
  • 并发编程经典实例,并发编程原理与概论
    并发编程经典实例,并发编程原理与概论
    并发编制程序的术语 并发 並且做多件事情 多线程 出现的一种格局,它选用四个线程来实行顺序。 二十三八线程是出现的一种情势,但不是当世无双的款