澳门新萄京 10

开始接触

走进异步编制程序的社会风气 – 开端接触 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。

  【注意】每一趟运维的结果只怕两样。不管哪次调节和测量检验,绝超过53%光阴都浪费前几次调用(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>
对象取结果,纵然还未曾结果的话,将卡住,直有结果再次回到截止。

 

二、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》

发表评论

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