C#中的Task使用方式
前言
在 C# 中,Task代表一個(gè)異步操作。它允許你在不阻塞主線程的情況下執(zhí)行耗時(shí)的操作,從而提高應(yīng)用程序的響應(yīng)性和性能。本教程將詳細(xì)介紹 C# 中的Task。
Task 的基本概念
Task是.NET Framework 4.0 引入的一種異步編程模型,它代表一個(gè)可能尚未完成的操作。
Task可以表示任何異步操作,例如文件讀取、網(wǎng)絡(luò)請求、數(shù)據(jù)庫查詢等。與傳統(tǒng)的異步編程模型相比,Task提供了一種更加簡潔和高效的方式來處理異步操作。
創(chuàng)建 Task
使用異步方法
C# 中的異步方法通常以async關(guān)鍵字開頭,并返回一個(gè)Task或Task。
例如:
async Task<int> CalculateSumAsync() { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }
在這個(gè)例子中,CalculateSumAsync方法是一個(gè)異步方法,它返回一個(gè)Task,表示一個(gè)異步操作,該操作將計(jì)算從 0 到 99 的整數(shù)之和,并返回結(jié)果。
使用 Task.Run 方法
Task.Run方法可以將一個(gè)委托作為參數(shù),并在一個(gè)新的線程上執(zhí)行該委托。
例如:
Task<int> task = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; });
在這個(gè)例子中,Task.Run方法將一個(gè) lambda 表達(dá)式作為參數(shù),該表達(dá)式計(jì)算從 0 到 99 的整數(shù)之和,并返回結(jié)果。
Task.Run方法返回一個(gè)Task,表示在新線程上執(zhí)行的異步操作。
等待 Task 完成
使用 await 關(guān)鍵字
await關(guān)鍵字用于等待一個(gè)Task完成。當(dāng)使用await關(guān)鍵字等待一個(gè)Task時(shí),當(dāng)前方法會(huì)暫停執(zhí)行,直到Task完成。
例如:
async Task<int> CalculateSumAsync() { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; } async Task Main() { int result = await CalculateSumAsync(); Console.WriteLine(result); }
在這個(gè)例子中,Main方法是一個(gè)異步方法,它調(diào)用CalculateSumAsync方法,并使用await關(guān)鍵字等待該方法完成。
一旦CalculateSumAsync方法完成,result變量將被賦值為該方法的返回值,并在控制臺(tái)上輸出結(jié)果。
使用 Task.Wait 方法
Task.Wait方法用于等待一個(gè)Task完成。與await關(guān)鍵字不同,Task.Wait方法會(huì)阻塞當(dāng)前線程,直到Task完成。
例如:
Task<int> task = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }); task.Wait(); int result = task.Result; Console.WriteLine(result);
在這個(gè)例子中,task.Wait()方法會(huì)阻塞當(dāng)前線程,直到task完成。
一旦task完成,result變量將被賦值為task的返回值,并在控制臺(tái)上輸出結(jié)果。
處理 Task 的異常
使用 try-catch 塊
當(dāng)?shù)却粋€(gè)Task時(shí),可以使用try-catch塊來捕獲Task中發(fā)生的異常。
例如:
async Task<int> CalculateSumAsync() { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } throw new Exception("An error occurred."); return sum; } async Task Main() { try { int result = await CalculateSumAsync(); Console.WriteLine(result); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
在這個(gè)例子中,CalculateSumAsync方法在計(jì)算總和的過程中拋出了一個(gè)異常。
在Main方法中,使用try-catch塊來捕獲這個(gè)異常,并在控制臺(tái)上輸出異常消息。
使用 Task.Exception 屬性
Task.Exception屬性返回一個(gè)AggregateException,其中包含了Task中發(fā)生的所有異常。
例如:
Task<int> task = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } throw new Exception("An error occurred."); return sum; }); try { task.Wait(); int result = task.Result; Console.WriteLine(result); } catch (AggregateException ex) { foreach (var innerException in ex.InnerExceptions) { Console.WriteLine(innerException.Message); } }
在這個(gè)例子中,task.Wait()方法會(huì)阻塞當(dāng)前線程,直到task完成。
如果task中發(fā)生了異常,catch塊將捕獲AggregateException,并遍歷其中的所有異常,在控制臺(tái)上輸出異常消息。
Task 的延續(xù)
使用 ContinueWith 方法
ContinueWith方法用于在一個(gè)Task完成后執(zhí)行另一個(gè)操作。
例如:
Task<int> task = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }); task.ContinueWith(t => { Console.WriteLine(t.Result); });
在這個(gè)例子中,task.ContinueWith方法在task完成后執(zhí)行一個(gè) lambda 表達(dá)式,該表達(dá)式輸出task的結(jié)果。
使用 await 關(guān)鍵字和異步方法
也可以使用await關(guān)鍵字和異步方法來實(shí)現(xiàn)Task的延續(xù)。
例如:
async Task<int> CalculateSumAsync() { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; } async Task PrintResultAsync(int result) { Console.WriteLine(result); } async Task Main() { int result = await CalculateSumAsync(); await PrintResultAsync(result); }
在這個(gè)例子中,Main方法首先調(diào)用CalculateSumAsync方法,并使用await關(guān)鍵字等待該方法完成。然后,它調(diào)用PrintResultAsync方法,并使用await關(guān)鍵字等待該方法完成。
這樣,PrintResultAsync方法就作為CalculateSumAsync方法的延續(xù)執(zhí)行。
Task 的并行執(zhí)行
使用多個(gè) Task
可以同時(shí)啟動(dòng)多個(gè)Task,并等待它們?nèi)客瓿伞?/p>
例如:
Task<int> task1 = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }); Task<int> task2 = Task.Run(() => { int product = 1; for (int i = 1; i <= 10; i++) { product *= i; } return product; }); Task.WaitAll(task1, task2); int sum = task1.Result; int product = task2.Result; Console.WriteLine(sum); Console.WriteLine(product);
在這個(gè)例子中,同時(shí)啟動(dòng)了兩個(gè)Task,一個(gè)計(jì)算從 0 到 99 的整數(shù)之和,另一個(gè)計(jì)算從 1 到 10 的整數(shù)之積。然后,使用Task.WaitAll方法等待這兩個(gè)Task全部完成,并輸出結(jié)果。
使用 Task.WhenAll 方法
Task.WhenAll方法返回一個(gè)Task,當(dāng)所有傳入的Task都完成時(shí),這個(gè)Task才完成。
例如:
Task<int> task1 = Task.Run(() => { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }); Task<int> task2 = Task.Run(() => { int product = 1; for (int i = 1; i <= 10; i++) { product *= i; } return product; }); Task<int[]> tasks = Task.WhenAll(task1, task2); int[] results = await tasks; int sum = results[0]; int product = results[1]; Console.WriteLine(sum); Console.WriteLine(product);
在這個(gè)例子中,使用Task.WhenAll方法等待兩個(gè)Task全部完成,并返回一個(gè)包含兩個(gè)Task結(jié)果的數(shù)組。然后,使用await關(guān)鍵字等待這個(gè)Task完成,并輸出結(jié)果。
總結(jié)
Task是 C# 中一種強(qiáng)大的異步編程模型,它允許你在不阻塞主線程的情況下執(zhí)行耗時(shí)的操作。
通過使用Task,你可以提高應(yīng)用程序的響應(yīng)性和性能,同時(shí)保持代碼的簡潔和可讀性。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
c# 執(zhí)行動(dòng)態(tài)編譯的方法實(shí)例詳解
在C#中執(zhí)行動(dòng)態(tài)編譯的一種方法是使用 CSharpCodeProvider 類,這篇文章主要介紹了c# 執(zhí)行動(dòng)態(tài)編譯的方法,需要的朋友可以參考下2024-03-03unity shader實(shí)現(xiàn)玻璃折射效果
這篇文章主要為大家詳細(xì)介紹了unity shader實(shí)現(xiàn)玻璃折射效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04WinForm實(shí)現(xiàn)基于BindingSource的方法擴(kuò)展
這篇文章主要介紹了WinForm實(shí)現(xiàn)基于BindingSource的方法擴(kuò)展,需要的朋友可以參考下2014-08-08基于C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲 C#抓取網(wǎng)頁Html源碼
這篇文章主要為大家詳細(xì)介紹了基于C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲的相關(guān)資料,即C#抓取網(wǎng)頁Html源碼,感興趣的小伙伴們可以參考一下2016-03-03C#實(shí)現(xiàn)在Excel中插入和操作切片器
本文主要介紹了如何使用C#在Excel中插入和操作切片器,包括插入切片器到透視表和表格,修改切片器屬性以及刪除切片器,主要使用了Spire.XLSfor.NET庫來實(shí)現(xiàn)這些功能,需要的朋友可以參考下2025-03-03C# OpenCvSharp實(shí)現(xiàn)去除字母后面的雜線
這篇文章主要為大家詳細(xì)介紹了C#如何使用OpenCvSharp實(shí)現(xiàn)去除字母后面的雜線效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11C#實(shí)現(xiàn)抓取和分析網(wǎng)頁類實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)抓取和分析網(wǎng)頁類,實(shí)例分析了C#抓取及分析網(wǎng)頁中文本及連接的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05