异步编程
Posted RC7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步编程相关的知识,希望对你有一定的参考价值。
开始学习异步编程之前,先让我们来看下面一个异步编程的示例:
1 class MyDownloadString 2 { 3 private Stopwatch sw = new Stopwatch(); 4 5 public void Run() 6 { 7 const int LargeNumber = 9000000; 8 sw.Start(); 9 string site1 = "http://news.163.com"; 10 string site2 = "http://www.163.com"; 11 Task<int> t1 = CountCharacterAsync(1, site1); 12 Task<int> t2 = CountCharacterAsync(2, site2); 13 CountToALargeNumber(1, LargeNumber); 14 CountToALargeNumber(2, LargeNumber); 15 CountToALargeNumber(3, LargeNumber); 16 CountToALargeNumber(4, LargeNumber); 17 Console.WriteLine("Chars in " + site1 + " : {0}", t1.Result); 18 Console.WriteLine("Chars in " + site2 + " : {0}", t2.Result); 19 } 20 21 private async Task<int> CountCharacterAsync(int id, string site) 22 { 23 WebClient wc = new WebClient(); 24 Console.WriteLine("Starting Call {0} : {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds); 25 string result = await wc.DownloadStringTaskAsync(new Uri(site)); 26 Console.WriteLine(" Call {0} completed: {1, 4:N0} ms", id, sw.Elapsed.TotalMilliseconds); 27 return result.Length; 28 } 29 30 private void CountToALargeNumber(int id, int value) 31 { 32 for (long i = 0; i < value; i++) ; 33 Console.WriteLine(" End counting {0} : {1,4:N0} ms", id, sw.Elapsed.TotalMilliseconds); 34 } 35 }
以上就是一个异步编程的典型示例,重点要理解async和await关键字的使用,以及Task<T>的用法。
async用于标识一个方法问异步方法,比如上面的CountCharacterAsync方法,在标识有async的方法内部,必须至少要出现一个await关键字,否则编译器会报错。await应该出现在调用耗时操作之前,当程序执行到await标识的操作时,会另起一个线程去执行它,因此主线程就不会被阻塞。
我们再来看Run()方法,首先创建两个Task,分别用于统计两个网站的字符数,然后中间插入一些耗时操作(其实就是一些空循环)来模拟实际程序执行其他代码所消耗的时间,最后我们调用t1.Result和t2.Result来输出统计结果,程序运行的时候我们会发现, 执行CountCharacterAsync方法的时候,程序并没有等待wc.DownloadStringTaskAsync(new Uri(site))执行完毕才去执行CountToALargeNumber(1, LargeNumber),而是立即返回到调用它的地方并执行后续的代码,直到我们要是用t1.Result和t2.Result的时候才开始等待(也有可能这时候t1.Result和t2.Result早就被计算出来了)。
以上是关于异步编程的主要内容,如果未能解决你的问题,请参考以下文章