线程也疯狂—–异步编制程序

Async&Await 轻松利用

采用Async&Await的非常重要指标是惠及举行异步操作,因为.net
4.0
以前进行异步操作时相比较复杂的,重即使经过调用微软提供的异步回调方法举行编制程序,如若遇上需求团结达成的格局显得十三分发烧,.net的依次版本都有谈得来首选的能力,像.NET1.第11中学的委托,.NET2.0中的泛型,.NET3.0中的Linq,.NET4.0中的Dynimac,.net4.5首选的就是异步编程,大家只需求掌握TASK+异步函数就足以兑现异步编制程序。

async:告诉CL昂科雷那是一个异步函数。

await:  将Task<TResult>重临值的函数实行异步管理。

 

亲自去做指标:获取网站JS代码,并在分界面突显。

 1  private static async Task<string> DownloadStringWithRetries(string uri)
 2         {
 3             using (var client = new HttpClient())
 4             {
 5                 // 第1 次重试前等1 秒,第2 次等2 秒,第3 次等4 秒。
 6                 var nextDelay = TimeSpan.FromSeconds(1);
 7                 for (int i = 0; i != 3; ++i)
 8                 {
 9                     try
10                     {
11                         return await client.GetStringAsync(uri);
12                     }
13                     catch
14                     {
15                     }
16                     await Task.Delay(nextDelay);
17                     nextDelay = nextDelay + nextDelay;
18                 }
19                 // 最后重试一次,以便让调用者知道出错信息。
20                 return await client.GetStringAsync(uri);
21             }
22         }

 1  static  void Main(string[] args)
 2         {
 3             Console.WriteLine("获取百度数据");
 4             ExecuteAsync();
 5             Console.WriteLine("线程结束");
 6             Console.ReadLine();
 7         }
 8 
 9         public static async void ExecuteAsync()
10         {
11            string text = await DownloadStringWithRetries("http://wwww.baidu.com");
12            Console.WriteLine(text);
13         }

运作结果发掘,首先获得百度数据,线程停止,最后展现HTML代码,那是因为异步开启了新的线程,并不会导致线程阻塞。

 

任务

  在应用义务从前,针对线程的调用大多都用线程池提供的静态方法QueueUserWorkItem,然则那个函数有不胜枚举的范围,个中最大的主题素材纵然未有内部机制得以让开辟者知道操作在如何时候做到,也一直不编写制定在操作完毕时收获重返值,微软为了消除那个主题素材引进了职务的定义。

 首先构造贰个Task<TResult>对象,并为TResult传递再次回到值,开端职责之后等待它并赶回结果,示例代码:

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("开始进行计算");
 4            // ThreadPool.QueueUserWorkItem(Sum, 10);
 5             Task<int> task = new Task<int>(Sum, 100);
 6             task.Start();
 7             //显示等待获取结果
 8             task.Wait();
 9             //调用Result时,等待返回结果
10             Console.WriteLine("程序结果为 Sum = {0}",task.Result);
11             Console.WriteLine("程序结束");
12             Console.ReadLine();
13         }
14 
15         public static int Sum(object i)
16         {
17             var sum = 0;
18             for (var j = 0; j <= (int) i; j++)
19             {
20                 Console.Write("{0} + ",sum);
21                 sum += j;
22             }
23             Console.WriteLine( " = {0}",sum);
24             return sum;
25         }

除此而外wait等待单个职分外,task还提供了等待多少个职分,WaitAny和WaitAll,它阻挡调用线程,直到数组中有所的Task对象完成。

什么样是异步?

异步管理不用阻塞当前线程来等待管理到位,而是允许传承操作,直至别的线程将拍卖完结,并回调公告此线程。

异步和多线程

同样点:幸免调用线程阻塞,进而升高软件的可响应性。

不同点:

异步操作无须额外的线程担任,而且动用回调的措施开展拍卖,在统筹精美的图景下,管理函数能够无需接纳分享变量(纵然不可能完全不用,最起码能够减少分享变量的数目),缩短了死锁的大概。C#5.0 .NET4.5
未来主要字Async和Await的行使,使得异步编制程序变得老大轻便。

二十多线程中的处理程序依旧是各类试行,然则多线程的缺欠也长期以来明显,线程的施用(滥用)会给系统带来上下文切换的额外负责。并且线程间的分享变量也许变成死锁的面世。

异步应用场景及原理

异步重要选择于IO操作,数据库访谈,磁盘操作,Socket访谈、HTTP/TCP互联网通讯 

由来:对于IO操作并无需CPU实行过多的测算,这一个数量首要透过磁盘进行拍卖,假设进展共同通讯不恐怕收场,要求创设更加多的线程能源,线程的数目上下文频仍的切换也是对财富的浪费,针对IO操作无需单独的分配一个线程来拍卖。

比方表达:

操作:服务器收到HTTP央求对数据库举办操作然后归来

一齐管理须要的线程会被堵塞,异步管理央求的线程不会卡住。

图片 1

 

裁撤义务

职务的吊销一样选取的是.NET
Framework的正式裁撤操作格局,首先须求创制贰个CancellationTokenSource对象,然后在函数中加入参数CancellationToken,将CancellationTokenSource的Token传递给艺术,然后调用IsCancellationRequested获取是还是不是业已撤消该值实行判别。

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("开始进行计算");
 4             // ThreadPool.QueueUserWorkItem(Sum, 10);
 5             var  ctx = new CancellationTokenSource();
 6             var task = new Task<int>(() => Sum(ctx.Token, 100000));
 7             task.Start();
 8             //显示等待获取结果
 9             //task.Wait(ctx.Token);
10             Thread.Sleep(1000);
11             ctx.Cancel();
12             //调用Result时,等待返回结果
13             Console.WriteLine("程序结果为 Sum = {0}", task.Result);
14             Console.WriteLine("程序结束");
15             Console.ReadLine();
16         }
17 
18         public static int Sum(CancellationToken cts, object i)
19         {
20             var sum = 0;        
21             for (var j = 0; j <= (int)i; j++)
22             {
23                 if (cts.IsCancellationRequested) return sum;
24                 Thread.Sleep(50);
25                 Console.Write("{0} + ", sum);
26                 sum += j;
27             }
28             Console.WriteLine(" = {0}", sum);
29             return sum;
30         }

前言

本节入眼介绍异步编程中Task、Async和Await的基础知识。

任务达成后自动运转新职务

骨子里的开荒应用中,平日出现一遍职责成功后立时运转别的四个职责,并且不可见使线程阻塞,在职分未有到位时调用result会使程序阻塞,无法查看职责的进行进程,TASK提供了三个主意ContinueWith,它不会卡住任何线程,当第一个职责完毕时,会应声运转第二个职责。

 1 static void Main(string[] args)
 2         {
 3             Console.WriteLine("开始进行计算");
 4             // ThreadPool.QueueUserWorkItem(Sum, 10);
 5             var  ctx = new CancellationTokenSource();
 6             var task = new Task<int>(() => Sum(ctx.Token, 100000));
 7             task.Start();
 8             var cwt = task.ContinueWith(p =>
 9             {
10                 Console.WriteLine("task result ={0} ",task.Result);
11             });
12             //显示等待获取结果
13             //task.Wait(ctx.Token);
14             Thread.Sleep(1000);
15             ctx.Cancel();
16             //调用Result时,等待返回结果
17             Console.WriteLine("程序结果为 Sum = {0}", task.Result);
18             Console.WriteLine("程序结束");
19             Console.ReadLine();
20         }
21 
22         public static int Sum(CancellationToken cts, object i)
23         {
24             var sum = 0;        
25             for (var j = 0; j <= (int)i; j++)
26             {
27                 if (cts.IsCancellationRequested) return sum;
28                 Thread.Sleep(50);
29                 Console.Write("{0} + ", sum);
30                 sum += j;
31             }
32             Console.WriteLine(" = {0}", sum);
33             return sum;
34         }

相关文章