【C#】50.使用await操作连续的异步任务

来源:互联网 发布:2017最新网络神曲 编辑:程序博客网 时间:2024/05/22 06:44

本篇主要说明一下使用await处理连续异步任务后,程序的条理会变得较为清晰。


async static Task<string> GetInfoAsync(string name){Console.WriteLine("Task {0} started!", name);await Task.Delay(2000);if(name == "Async 2")throw new Exception("Boom!");return string.Format("Task {0} 运行在线程id为 {1}的线程. 是否是线程池线程: {2}",name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);}

async static Task AsynchronyWithAwait(){try{string result = await GetInfoAsync("Async 1");Console.WriteLine(result);result = await GetInfoAsync("Async 2");Console.WriteLine(result);}catch (Exception ex){Console.WriteLine(ex);}}


主线程函数:
static void Main(string[] args){Task t = AsynchronyWithAwait();t.Wait();Console.Read();}

函数AsynchronyWithAwait中,两次使用了await,他们都将等待程序处理完毕后才会继续执行,因此两者执行的先后次序就是两者的上下文先后关系。在第二个await中的任务抛出了异常且被正确处理了,因此await也可以像正常使用try catch那样处理异常,无需将异常处理写在线程执行的函数体中。



然后我们来看下如何使用TPL方式(也就是ContinueWith)方式先后执行异步任务:

static Task AsynchronyWithTPL(){var containerTask = new Task(() =>   {      Task<string> t = GetInfoAsync("TPL 1");     t.ContinueWith(task => {Console.WriteLine(t.Result);Task<string> t2 = GetInfoAsync("Async 2");t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Result),        TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);//不会被运行,因为NotOnFaulted,而t2是抛出异常的t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Exception.InnerException),        TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);//会被执行},TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);         t.ContinueWith(task => Console.WriteLine(t.Exception.InnerException),        TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);//不会被运行,因为t并没有发生异常;如果将TPL 1改为Async 2,那么这里将被运行而上面那些不会被运行。  });     containerTask.Start();     return containerTask;}

Task t = AsynchronyWithTPL();t.Wait();


可以看到,使用ContinueWith的方式使得顺序执行复杂了好多,而且需要使用一个containerTask来包裹两个Task。第一个ContinueWith里面定义了第一个任务t (TPL 1)在两种情况下(无异常和有异常)各自的处理方法;而后在第一个任务运行完毕后,再运行第二个任务(Async 2)并且指定要处理异常的ContinueWith。


0 0
原创粉丝点击