有人可以解释asynchronous/等待?
我开始学习C#5.0中的asynchronous/等待,而我完全不理解它。 我不明白它如何用于并行。 我已经尝试了以下非常基本的程序:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Task task1 = Task1(); Task task2 = Task2(); Task.WaitAll(task1, task2); Debug.WriteLine("Finished main method"); } public static async Task Task1() { await new Task(() => Thread.Sleep(TimeSpan.FromSeconds(5))); Debug.WriteLine("Finished Task1"); } public static async Task Task2() { await new Task(() => Thread.Sleep(TimeSpan.FromSeconds(10))); Debug.WriteLine("Finished Task2"); } } }
这个程序只是阻止对Task.WaitAll()
的调用,并且永远不会结束。 有人可以向我解释为什么? 我敢肯定,我只是缺less一些简单的东西,或者只是没有正确的思维模式,没有任何博客或MSDN文章在帮助。
我build议你从我的介绍开始async
/ await
和后续与官方的TAP的MSDN文档 。
正如我在我的介绍博客文章中提到的,有几个Task
成员从TPL持有,并没有使用纯async
代码。 new Task
和Task.Start
应该replace为Task.Run
(或TaskFactory.StartNew
)。 同样, Thread.Sleep
应该replace为Task.Delay
。
最后,我build议你不要使用Task.WaitAll
; 您的控制台应用程序应该Wait
使用Task.WhenAll
的单个Task
。 随着所有这些变化,你的代码将如下所示:
class Program { static void Main(string[] args) { MainAsync().Wait(); } public static async Task MainAsync() { Task task1 = Task1(); Task task2 = Task2(); await Task.WhenAll(task1, task2); Debug.WriteLine("Finished main method"); } public static async Task Task1() { await Task.Delay(5000); Debug.WriteLine("Finished Task1"); } public static async Task Task2() { await Task.Delay(10000); Debug.WriteLine("Finished Task2"); } }
你的任务从来没有完成,因为他们从来没有开始运行
我会Task.Factory.StartNew
创build一个任务,并启动它。
public static async Task Task1() { await Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(5))); Debug.WriteLine("Finished Task1"); } public static async Task Task2() { await Task.Factory.StartNew(() => Thread.Sleep(TimeSpan.FromSeconds(10))); Debug.WriteLine("Finished Task2"); }
作为一个方面说明,如果你真的只是试图在一个asynchronous方法暂停,没有必要阻止整个线程,只需使用Task.Delay
public static async Task Task1() { await Task.Delay(TimeSpan.FromSeconds(5)); Debug.WriteLine("Finished Task1"); } public static async Task Task2() { await Task.Delay(TimeSpan.FromSeconds(10)); Debug.WriteLine("Finished Task2"); }
asynchronous和等待是在任务(线程)完成之后,控制应该从何处继续的代码位置的标记。 这是一个详细的YouTubevideo,以示范的方式解释了这个概念http://www.youtube.com/watch?v=V2sMXJnDEjM
如果你愿意,你也可以阅读这个coodeproject文章,以更直观的方式解释相同。 http://www.codeproject.com/Articles/599756/Five-Great-NET-Framework-4-5-Features#Feature1:-“Async”and“Await”(Codemarkers )
理解C#任务,asynchronous并等待
C#任务
任务类是一个asynchronous任务包装。 Thread.Sleep(1000)可以停止运行1秒的线程。 而Task.Delay(1000)不会停止当前的工作。 见代码:
public static void Main(string[] args){ TaskTest(); } private static void TaskTest(){ Task.Delay(5000); System.Console.WriteLine("task done"); }
运行时,“任务完成”将立即显示。 所以我可以假定来自任务的每个方法都应该是asynchronous的。 如果我将TaskTest()replace为Task.Run(()=> TaskTest()),则完成的任务将不会显示出来,直到我追加一个Console.ReadLine(); Run方法之后。
在内部,Task类表示一个状态机中的线程状态。 状态机中的每个状态都有几个状态,如Start,Delay,Cancel和Stop。
asynchronous和等待
现在,你可能想知道如果所有的任务是asynchronous的,Task.Delay的目的是什么? 接下来,让我们真正使用asynchronous延迟正在运行的线程并等待
public static void Main(string[] args){ TaskTest(); System.Console.WriteLine("main thread is not blocked"); Console.ReadLine(); } private static async void TaskTest(){ await Task.Delay(5000); System.Console.WriteLine("task done"); }
asynchronous告诉调用者,我是一个asynchronous方法,不要等待我。 在TaskTest()内部等候请求等待asynchronous任务。 现在,运行后,程序将等待5秒钟,以显示任务完成文本。
取消任务
由于任务是一个状态机,所以在任务运行时必须有一种方法来取消任务。
static CancellationTokenSource tokenSource = new CancellationTokenSource(); public static void Main(string[] args){ TaskTest(); System.Console.WriteLine("main thread is not blocked"); var input=Console.ReadLine(); if(input=="stop"){ tokenSource.Cancel(); System.Console.WriteLine("task stopped"); } Console.ReadLine(); } private static async void TaskTest(){ try{ await Task.Delay(5000,tokenSource.Token); }catch(TaskCanceledException e){ //cancel task will throw out a exception, just catch it, do nothing. } System.Console.WriteLine("task done"); }
现在程序运行时,可以input“stop”来取消延时任务。