但在决定台出口示例时日常会动用 C

走进异步编制程序的世界 – 开首接触 async/await

 

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

  涉及 C# 5.0 引进的 async/await,但在调节台出口示例时日常会动用 C#
6.0 的 $”” 来拼接字符串,也正是string.Format() 方法。

 

目录

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

 

一、What’s 异步?

     运行程序时,系统会在内部存储器中制造一个新的长河。进度是组成运转程序财富的联谊。

     在进程之中,有称得上线程的水源对象,它意味着的是真的的实践顺序。系统会在 Main
方法的率先行语句就从头线程的实践。

 

     线程:

     ①私下认可地方,二个进程只含有二个线程,从程序的起来到履行完成;

   
 ②线程能够派生自其余线程,所以七个经过能够分包差异情状的多个线程,来施行顺序的不及部分;

     ③二个进程中的四个线程,将分享该进程的能源;

     ④类别为计算机实施所安插的单元是线程,而非进度。

 

   
 日常的话大家写的调整台程序都只利用了二个线程,从第一条语句按梯次试行到最终一条。但在众多的事态下,这种简单的模子会在质量或客户体验上倒霉。

   
 例如:服务器要同期管理来自四个客商端程序的伸手,又要等待数据库和别的设备的响应,那将严重影响属性。程序不应该将时刻浪费在响应上,而要在等候的同一时候进行别的任务!

   
 现在大家伊始踏入异步编程。在异步程序中,代码无需根据编写时的逐龙马精气神推行。那时大家须要用到
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>
对象取结果,假设还未结果的话,将卡住,直有结果回到截止。

 

二、async/await 结构

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

     同步方法:三个程序调用某些方法,等到其实施到位之后才开展下一步操作。那也是暗许的款型。

     异步方法:贰个前后相继调用有些方法,在管理完了早前就再次来到该方法。通过
async/await 我们就足以兑现那种类型的章程。

 

     async/await 结构可分为三片段:

     (1)调用方法:该方法调用异步方法,然后在异步方法试行其职责的时候继续实行;

     (2)异步方法:该措施异步实践专业,然后任何时候回到到调用方法;

     (3)await
表明式:用于异步方法内部,建议须求异步推行的职务。多少个异步方法能够富含八个await 表明式(海市蜃楼 await 表明式的话 IDE 会发出警告)。

 

  未来我们来分析一下演示。

图片 9

  图2-1

 

 三、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)此外:佚名情势和 拉姆da
表明式也能够用作异步对象;async 是二个上下文关键字;关键字 async
必得在回到类型前。

 图片 10

图3-1 异步方法的粗略结构图

 

小结

  1.剖判了经过和线程的概念

  2.异步的简练用法

  3.async/await 结构体

  4.异步方塞尔维亚共和国语法结构

 

传送门

  下篇:《[走进异步编制程序的世界 –

浅析异步方法(上)](

浅析异步方法(下)](

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

 


本文首联:

【参考】《Illustrated C# 2012》

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website