你好,我是阿輝,
之前學習了執行緒池,知道了它有很多好處,
使用執行緒池可以使我們在減少并行度花銷時節省作業系統資源,可認為執行緒池是一個抽象層,其向程式員隱藏了使用執行緒的細節,使我們可以專心處理程式邏輯,而不是各種執行緒問題,
但也不是說我們所有的專案中都上執行緒池,其實它也有很多弊端,比如我們需要自定義使用異步委托的方式才可以將執行緒中的訊息或例外傳遞出來,這些如果在一個大的軟體系統中,會導致軟體結構過于混亂,各個執行緒之間訊息傳遞來傳遞去的,如果發生沒有處理掉的例外,很容易導致軟體出現致命錯誤,
為了解決這個問題,在.Net Framework 4.0中引入了一個新的異步操作的API,它叫任務并行庫(TPL),
那么接下來,讓我們一起來認識一下這個TPL,看看它到底有什么魔力可以把執行緒池中的棘手問題解決掉,
任務并行庫
TPL又被認為是執行緒池的有一個抽象,其對程式員隱藏了執行緒池互動的底層代碼,并只提供了更方便的細粒度的API,
TPL的核心是任務,一個任務代表一個異步操作,該操作可以通過多種方式運行,可以使用或不使用獨立執行緒運行,
TPL有一個關鍵優勢,就是一個任務可以通過多種方式和其它任務組合起來,
比如可以同時開啟多個任務,等待所有任務完成,然后運行一個任務對之前所有任務的結果進行一些計算,
可以使用AggregateException來捕獲底層任務內部所有例外,并允許單獨處理這些例外,在C#5.0中已經內置了對TPL的支持,允許我們使用心得await和async關鍵字以平滑的、舒服的方式操作任務,
一、創建任務
可以通過下面三種方式來創建任務,
var a1 = new Task(()=>TastMethod("執行緒01"));
a1.Start();
Task.Run(()=>TastMethod("執行緒001"));
Task.Factory.StartNew(()=>TastMethod("執行緒02"));
Task.Factory.StartNew(() => TastMethod("執行緒03"),TaskCreationOptions.LongRunning);
Console.ReadKey();
實體化的Tast屬性,必須進行啟動,任務才可以執行,其余的.NET已經做了內置,只需要使用就默認自動開啟,
在執行緒3開啟程序中,增加了TaskCreationOptions.LongRuning引數,它表示標記該任務為長時間運行,結果該任務將不會使用執行緒池,而在單獨的執行緒中運行,然而根據運行該任務的當前任務調度程式,運行方式可能不同,
二、使用任務執行基本操作
下面介紹下從任務中得到其計演算法回傳的結果,
static void Main(string[] args)
{
var a1 = new Task<int>(()=>TastMethod("執行緒01"));
a1.Start();
int result = a1.Result;
Console.WriteLine("result:" + result);
Console.ReadKey();
}
static int TastMethod(string name)
{
Console.WriteLine("執行緒名字:"+name+"Id:"+Thread.CurrentThread.ManagedThreadId+"是否屬于執行緒池:"+Thread.CurrentThread.IsThreadPoolThread);
return 40;
}

這里我們宣告并運行了執行緒01并等待結果,該任務會被放置在執行緒池中,并且主執行緒會等待,直到任務回傳前一直處于阻塞狀態,
其實也可以呼叫方法RunSynchronously()方法,使其特定運行在主執行緒,這是一個非常好的優化,可以避免使用執行緒池來執行非常短暫的操作,
三、處理任務中的例外
在異步任務中,對于例外的處理是非常重要的,
try
{
var a1 = new Task<int>(() => TastMethod("執行緒01",2));
a1.Start();
int result = a1.Result;
Console.WriteLine("result:" + result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
當程式啟動時,創建了一個任務并嘗試同步獲取任務結果,Result屬性的Get部分會使當前執行緒等待直到該任務結束,并將例外傳播給當前執行緒,此時通過try/catch是很容易捕獲到的(需要注意AggregateExceptiont,它被封裝起來,),
int result = a1.GetAwaiter().GetResult ;
上面這種情況無需封裝例外,可以使用GetAwaiter和GetResult方法來訪問任務結果,
小寄語
人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的,
原創不易,給個關注,
我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊、轉發 謝謝,
作者:阿輝 關注我:微信掃描下面二維碼,6T編程資料免費送, 微信公眾號:Andy阿輝
寫一些程式員的所思所想,希望對你有幫助,
出處:http://www.cnblogs.com/netxiaoahui/ 著作權宣告:本文著作權歸作者和博客園共有,歡迎轉載,
但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/298764.html
標籤:C#
