.Net中Task Parallel Library的進(jìn)階用法
在前一篇中,了解了Task的基本用法
如果一個(gè)方法返回Task,Task<T>,如何獲取Task的返回值,獲取值的過(guò)程會(huì)阻塞線程嗎?
static void Main(string[] args){ var result = DoWorkAsync().Result; Console.WriteLine(result); Console.WriteLine("我會(huì)什么時(shí)候顯示"); Console.ReadKey();}static Task<string> DoWorkAsync(){ return Task<string>.Factory.StartNew(() => {Thread.Sleep(3000);return "hello"; });}
可見(jiàn),Task的Result屬性可以獲取返回值,而且,獲取返回值的過(guò)程線程是被阻塞的。
是否可以不阻塞線程,又能拿到某個(gè)線程的返回值呢?ContinueWith方法在某個(gè)線程結(jié)束之后進(jìn)行,但同時(shí)不會(huì)阻塞線程。
static void Main(string[] args){ DoWorkAsync().ContinueWith((pre) => {Console.WriteLine(pre.Result); }); Console.WriteLine("我會(huì)什么時(shí)候顯示"); Console.ReadKey();}
但ContinueWith總會(huì)在某個(gè)線程結(jié)束之后進(jìn)行,是否可以對(duì)ContinueWith的過(guò)程控制一下呢?
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("我會(huì)什么時(shí)候顯示"); Console.ReadKey();}以上,當(dāng)沒(méi)有錯(cuò)誤的時(shí)候就把返回值顯示出來(lái),有錯(cuò)誤就把錯(cuò)誤信息顯示出來(lái)。
還可以通過(guò)Task的實(shí)例方法IsCompleted來(lái)判斷一個(gè)線程是否完成。
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("我會(huì)什么時(shí)候顯示"); Console.ReadKey();}Task的Status屬性,以及結(jié)合TaskStatus枚舉,可以判斷Task的狀態(tài)。
static void Main(string[] args){ var httpClient = new HttpClient(); Task<string> baiduTask = httpClient.GetStringAsync("http://www.baidu.com"); var httpClient2 = new HttpClient(); Task<string> sinaTask = httpClient2.GetStringAsync("http://www.sina.com.cn"); //等上面2個(gè)任務(wù)完成時(shí)這里再開始 Task<string[]> task = Task.WhenAll(baiduTask, sinaTask); task.ContinueWith(stringArray => {//如果任務(wù)完成if (task.Status == TaskStatus.RanToCompletion){ for (int i = 0; i < stringArray.Result.Length;i++) {Console.WriteLine(stringArray.Result[i].Substring(0,100)); }}else if (task.Status == TaskStatus.Canceled) //如果被取消{ Console.WriteLine("{0}這個(gè)任務(wù)被取消了",task.Id);}else //發(fā)生錯(cuò)誤{ Console.WriteLine("發(fā)生錯(cuò)誤了~~"); foreach (var item in task.Exception.InnerExceptions) {Console.WriteLine(item.Message); }} }); Console.ReadKey();}如果要控制Task的生命周期,可以考慮使用TaskCompletionSource<T>。
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("任務(wù)被取消");}else{ Console.WriteLine("發(fā)生錯(cuò)誤哦"); 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; } }以上,通過(guò)TaskCompletionSource<T>的SetResult給線程設(shè)置返回值,通過(guò)TaskCompletionSource<T>的.Task有獲取了線程。
另外,從.NET 4.5開始,Task的靜態(tài)方法FromResult,接收T類型,返回Task<T>。
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("任務(wù)被取消"); } else {Console.WriteLine("發(fā)生錯(cuò)誤哦");Console.WriteLine(intTask.Exception); } Console.ReadKey();}static Task<int> GetIntAsync(){ return Task.FromResult(10);}以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章:
1. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟2. .NET中實(shí)現(xiàn)對(duì)象數(shù)據(jù)映射示例詳解3. .NET Core Web APi類庫(kù)內(nèi)嵌運(yùn)行的方法4. 如何將asp.net core程序部署到Linux服務(wù)器5. ASP.NET MVC獲取多級(jí)類別組合下的產(chǎn)品6. ASP.NET MVC前臺(tái)動(dòng)態(tài)添加文本框并在后臺(tái)使用FormCollection接收值7. ASP.NET堆和棧三之引用類型對(duì)象拷貝和內(nèi)存分配8. 使用HttpClient增刪改查ASP.NET Web API服務(wù)9. ASP.NET MVC實(shí)現(xiàn)單個(gè)圖片上傳、限制圖片格式與大小并在服務(wù)端裁剪圖片10. asp.net生成HTML

網(wǎng)公網(wǎng)安備