C#中System.Threading.Tasks庫(kù)的使用
System.Threading.Tasks
是 .NET 中任務(wù)并行庫(kù)(Task Parallel Library, TPL)的核心組件,它提供了基于任務(wù)的異步編程模型,是現(xiàn)代 .NET 并發(fā)編程的基礎(chǔ)。
設(shè)計(jì)原理
1. 核心目標(biāo)
抽象并發(fā)工作:將并發(fā)操作抽象為"任務(wù)"概念
資源高效利用:自動(dòng)管理線程池資源
組合性:支持任務(wù)鏈?zhǔn)讲僮骱徒M合
取消支持:內(nèi)置取消操作機(jī)制
狀態(tài)跟蹤:提供任務(wù)生命周期管理
2. 關(guān)鍵組件
Task/Task<T>:表示異步操作的核心類
TaskScheduler:控制任務(wù)如何、何時(shí)被執(zhí)行
TaskFactory:提供創(chuàng)建和啟動(dòng)任務(wù)的便捷方法
CancellationToken:任務(wù)取消機(jī)制
TaskCompletionSource:手動(dòng)控制任務(wù)生命周期
3. 架構(gòu)層次
用戶層:開(kāi)發(fā)者直接使用的Task API
調(diào)度層:TaskScheduler管理任務(wù)執(zhí)行
線程池層:實(shí)際執(zhí)行工作的底層線程池
典型用法示例
示例1:基礎(chǔ)異步任務(wù)
// 創(chuàng)建并運(yùn)行簡(jiǎn)單任務(wù) Task.Run(() => { Console.WriteLine("任務(wù)在后臺(tái)線程執(zhí)行"); Thread.Sleep(1000); // 模擬工作 Console.WriteLine("任務(wù)完成"); }); // 帶返回值的任務(wù) Task<int> calculateTask = Task.Run(() => { Thread.Sleep(500); return 42; // 計(jì)算結(jié)果 }); // 等待任務(wù)完成并獲取結(jié)果 int result = await calculateTask; Console.WriteLine($"計(jì)算結(jié)果: {result}");
應(yīng)用場(chǎng)景:CPU密集型后臺(tái)計(jì)算,不阻塞UI線程。
示例2:任務(wù)組合與延續(xù)
// 創(chuàng)建三個(gè)任務(wù) Task<string> task1 = Task.Run(() => "Hello"); Task<string> task2 = Task.Run(() => "World"); Task<int> task3 = Task.Run(() => 2023); // 等待所有任務(wù)完成 await Task.WhenAll(task1, task2, task3); // 使用結(jié)果組合輸出 Console.WriteLine($"{task1.Result} {task2.Result} {task3.Result}"); // 任務(wù)延續(xù) Task continuation = task1.ContinueWith(t => { Console.WriteLine($"前一個(gè)任務(wù)的結(jié)果: {t.Result}"); }, TaskContinuationOptions.OnlyOnRanToCompletion);
應(yīng)用場(chǎng)景:并行執(zhí)行多個(gè)獨(dú)立操作,然后合并結(jié)果或執(zhí)行后續(xù)操作。
示例3:高級(jí)任務(wù)控制
// 使用TaskCompletionSource手動(dòng)控制任務(wù) var tcs = new TaskCompletionSource<string>(); // 模擬異步回調(diào) Timer timer = new Timer(_ => { try { // 模擬工作 string result = DateTime.Now.ToString(); tcs.SetResult(result); // 手動(dòng)完成任務(wù) } catch (Exception ex) { tcs.SetException(ex); // 手動(dòng)設(shè)置異常 } }, null, 1000, Timeout.Infinite); // 等待任務(wù)完成 try { string timeString = await tcs.Task; Console.WriteLine($"當(dāng)前時(shí)間: {timeString}"); } catch (Exception ex) { Console.WriteLine($"任務(wù)失敗: {ex.Message}"); }
應(yīng)用場(chǎng)景:將基于回調(diào)的異步API轉(zhuǎn)換為基于任務(wù)的異步模式(TAP)。
示例4:取消任務(wù)
var cts = new CancellationTokenSource(); CancellationToken token = cts.Token; // 創(chuàng)建可取消的任務(wù) Task longRunningTask = Task.Run(() => { for (int i = 0; i < 100; i++) { token.ThrowIfCancellationRequested(); // 檢查取消請(qǐng)求 Thread.Sleep(100); // 模擬工作 Console.WriteLine($"進(jìn)度: {i}%"); } }, token); // 3秒后取消任務(wù) cts.CancelAfter(3000); try { await longRunningTask; } catch (OperationCanceledException) { Console.WriteLine("任務(wù)被取消"); }
應(yīng)用場(chǎng)景:長(zhǎng)時(shí)間運(yùn)行的操作需要提供取消功能。
核心概念深入
1. 任務(wù)狀態(tài)機(jī)
任務(wù)有以下幾種狀態(tài):
Created
:已創(chuàng)建但未調(diào)度WaitingForActivation
:等待激活WaitingToRun
:已調(diào)度但未開(kāi)始執(zhí)行Running
:正在執(zhí)行WaitingForChildrenToComplete
:等待子任務(wù)完成RanToCompletion
:成功完成Canceled
:被取消Faulted
:因異常失敗
2. 任務(wù)調(diào)度策略
線程池調(diào)度器:默認(rèn)調(diào)度器,使用線程池線程
同步上下文調(diào)度器:在特定同步上下文(如UI線程)執(zhí)行
自定義調(diào)度器:可繼承TaskScheduler實(shí)現(xiàn)特殊調(diào)度邏輯
3. 異常處理
任務(wù)中的異常會(huì)被捕獲并存儲(chǔ)在 Task.Exception
屬性中,當(dāng)?shù)却蝿?wù)或訪問(wèn)Result屬性時(shí),這些異常會(huì)被重新拋出。
Task faultyTask = Task.Run(() => throw new InvalidOperationException("出錯(cuò)了")); try { await faultyTask; } catch (InvalidOperationException ex) { Console.WriteLine($"捕獲到異常: {ex.Message}"); }
最佳實(shí)踐
避免Task.Wait和Task.Result:可能導(dǎo)致死鎖,優(yōu)先使用await
合理使用ConfigureAwait:庫(kù)代碼應(yīng)使用ConfigureAwait(false)
注意任務(wù)生命周期:長(zhǎng)時(shí)間運(yùn)行的任務(wù)應(yīng)考慮取消支持
避免過(guò)度并行化:太多并行任務(wù)會(huì)導(dǎo)致線程池饑餓
正確處理異常:確保所有任務(wù)異常都被處理
性能考慮
任務(wù)創(chuàng)建開(kāi)銷:輕量級(jí)但非零成本,高頻場(chǎng)景考慮對(duì)象池
線程池壓力:大量短任務(wù)可能導(dǎo)致線程池頻繁調(diào)整
同步上下文:不必要地回到原始上下文會(huì)影響性能
System.Threading.Tasks
提供了強(qiáng)大而靈活的并發(fā)編程模型,是現(xiàn)代 .NET 應(yīng)用程序中處理異步和并行操作的首選方式。
到此這篇關(guān)于C#中System.Threading.Tasks庫(kù)的使用的文章就介紹到這了,更多相關(guān)C# System.Threading.Tasks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#簡(jiǎn)單工廠、工廠方法與抽象工廠的區(qū)別分析
看了網(wǎng)絡(luò)上很多關(guān)于設(shè)計(jì)模式的方法,有的模式看起來(lái)相似,但本質(zhì)還是區(qū)別很大的.像簡(jiǎn)單工廠,工廠方法和抽象工廠就有很明顯的區(qū)別.2013-03-03C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐
有時(shí)我們可能會(huì)遇到需要的資料或教程被分成了幾部分存放在多個(gè)PDF文件中,本文主要介紹了C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01