在前一篇中,了解了Task的基本用法
如果一个方法返回Task,Task
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | static void Main( string [] args) { var result = DoWorkAsync().Result; Console.WriteLine(result); Console.WriteLine( "我会什么时候显示" ); Console.ReadKey(); } static Task< string > DoWorkAsync() { return Task< string >.Factory.StartNew(() => { Thread.Sleep(3000); return "hello" ; }); }</ string ></ string > |
可见,Task的Result属性可以获取返回值,而且,获取返回值的过程线程是被阻塞的。
是否可以不阻塞线程,又能拿到某个线程的返回值呢?ContinueWith方法在某个线程结束之后进行,但同时不会阻塞线程。
1 2 3 4 5 6 7 8 9 | static void Main( string [] args) { DoWorkAsync().ContinueWith((pre) => { Console.WriteLine(pre.Result); }); Console.WriteLine( "我会什么时候显示" ); Console.ReadKey(); } |
但ContinueWith总会在某个线程结束之后进行,是否可以对ContinueWith的过程控制一下呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 | static void Main( string [] args) { DoWorkAsync().ContinueWith((pre) => { Console.WriteLine(pre.Result); }, TaskContinuationOptions.NotOnFaulted); DoWorkAsync().ContinueWith((pre) => { Console.WriteLine(pre.Exception); },TaskContinuationOptions.OnlyOnFaulted); Console.WriteLine( "我会什么时候显示" ); Console.ReadKey(); } |
以上,当没有错误的时候就把返回值显示出来,有错误就把错误信息显示出来。
还可以通过Task的实例方法IsCompleted来判断一个线程是否完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | static void Main( string [] args) { var doWorkTask = DoWorkAsync(); if (doWorkTask.IsCompleted) { Console.WriteLine(doWorkTask.Result); } else { doWorkTask.ContinueWith((pre) => { Console.WriteLine(pre.Result); }, TaskContinuationOptions.NotOnFaulted); doWorkTask.ContinueWith((pre) => { Console.WriteLine(pre.Exception); }, TaskContinuationOptions.OnlyOnFaulted); } Console.WriteLine( "我会什么时候显示" ); Console.ReadKey(); } |
Task的Status属性,以及结合TaskStatus枚举,可以判断Task的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void Main( string [] args) { var httpClient = new HttpClient(); var httpClient2 = new HttpClient(); //等上面2个任务完成时这里再开始 Task< string > task = Task.WhenAll(baiduTask, sinaTask); task.ContinueWith(stringArray => { //如果任务完成 if (task.Status == TaskStatus.RanToCompletion) { for ( int i = 0; i </ string ></ string ></ string > |
如果要控制Task的生命周期,可以考虑使用TaskCompletionSource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | static void Main( string [] args) { AsyncFactory.GetIntAsync().ContinueWith((prev) => { if (prev.Status == TaskStatus.RanToCompletion) { Console.WriteLine(prev.Result); } else if (prev.Status == TaskStatus.Canceled) { Console.WriteLine( "任务被取消" ); } else { Console.WriteLine( "发生错误哦" ); Console.WriteLine(prev.Exception); } }); Console.ReadKey(); } } public static class AsyncFactory { public static Task< int > GetIntAsync() { var tsc = new TaskCompletionSource< int >(); var timer = new System.Timers.Timer(2000); timer.AutoReset = false ; timer.Elapsed += (s, e) => { tsc.SetResult(10); timer.Dispose(); }; timer.Start(); return tsc.Task; } }</ int ></ int > |
以上,通过TaskCompletionSource
另外,从.NET 4.5开始,Task的静态方法FromResult,接收T类型,返回Task
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | static void Main( string [] args) { var intTask = GetIntAsync(); if (intTask.Status == TaskStatus.RanToCompletion) { Console.WriteLine(intTask.Result); } else if (intTask.Status == TaskStatus.Canceled) { Console.WriteLine( "任务被取消" ); } else { Console.WriteLine( "发生错误哦" ); Console.WriteLine(intTask.Exception); } Console.ReadKey(); } static Task< int > GetIntAsync() { return Task.FromResult(10); }</ int > |
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对IT俱乐部的支持。如果你想了解更多相关内容请查看下面相关链接