走进异步编制程序的世界,起头接触

走进异步编制程序的社会风气 - 起初接触 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 方法的数11遍调用是在 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 沃特ch = 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}:{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 < 五千; i ) 58 { 59 s = i; 60 } 61 62 Console.WriteLine($"id = {id} 的 ExtraOperation 方法成功:{Watch.ElapsedMilliseconds} 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》

本文由星彩网app下载发布于计算机编程,转载请注明出处:走进异步编制程序的世界,起头接触

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。