Task 是非同步程式設計(asynchronous programming)的一個核心概念,它代表一個非同步操作。
用來表示非同步工作的類別,實現非同步處理、平行運算、不阻塞 UI。
命名空間System.Threading.Tasks。
在 C# 中常見的定義方式如下:
| Task t = Task.Run(() => { |
| |
| Debug.WriteLine("背景執行的程式碼"); |
| }); |
如果這個背景工作會傳回一個結果,例如整數,則會使用泛型版本 Task<T>:
| Task<int> t = Task.Run(() => { |
| return 42; |
| }); |
非同步處理資料、不中斷主執行緒
| using System; |
| using System.Threading; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("主執行緒開始"); |
| |
| Task.Run(() => |
| { |
| Debug.WriteLine("資料處理開始"); |
| Thread.Sleep(2000); |
| Debug.WriteLine("資料處理完成"); |
| }); |
| |
| |
| for (int i = 0; i < 5; i++) |
| { |
| Debug.WriteLine("主執行緒仍在執行中..."); |
| Thread.Sleep(500); |
| } |
| |
| Debug.WriteLine("主執行緒結束"); |
| } |
| } |
- Task.Run(...):啟動一個新的非同步工作。
- Thread.Sleep(...):模擬一個耗時的處理(例如存取資料庫、網路請求等)。
- ContinueWith(...):當上面的任務完成後再執行。
- task.Wait():主執行緒等待該 Task 完成,避免主程式提早結束。
非阻塞主執行緒
| using System; |
| using System.Threading; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("主執行緒開始"); |
| |
| |
| Task.Run(() => |
| { |
| Debug.WriteLine("背景工作開始執行..."); |
| Thread.Sleep(3000); |
| Debug.WriteLine("背景工作結束"); |
| }) |
| .ContinueWith(t => |
| { |
| Debug.WriteLine("後續處理完成"); |
| }); |
| |
| |
| for (int i = 0; i < 5; i++) |
| { |
| Debug.WriteLine($"主執行緒正在執行其他工作... {i}"); |
| Thread.Sleep(500); |
| } |
| |
| Debug.WriteLine("主執行緒結束"); |
| } |
| } |
- 背景任務透過 Task.Run 執行
- ContinueWith task結束後,可接後續任務執行
多個任務平行執行
| using System; |
| using System.Threading; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("主執行緒啟動"); |
| |
| for (int i = 1; i <= 3; i++) |
| { |
| int taskNum = i; |
| Task.Run(() => |
| { |
| Debug.WriteLine($"Task {taskNum} 開始"); |
| Thread.Sleep(1000 * taskNum); |
| Debug.WriteLine($"Task {taskNum} 結束"); |
| }); |
| } |
| |
| Debug.WriteLine("主執行緒正在執行其他事"); |
| } |
| } |
從非同步任務中回傳資料
雖然不能 await 結果,但你可以使用 ContinueWith 來處理結果。
| using System; |
| using System.Threading; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("主執行緒開始"); |
| |
| Task task = Task.Run(() => |
| { |
| Thread.Sleep(1500); |
| return 42; |
| }); |
| |
| task.ContinueWith(t => |
| { |
| Debug.WriteLine($"收到非同步結果:{t.Result}"); |
| }); |
| |
| Debug.WriteLine("主執行緒繼續執行"); |
| } |
| } |
模擬非同步下載
| using System; |
| using System.Net; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("開始模擬下載"); |
| |
| Task.Run(() => |
| { |
| using (WebClient client = new WebClient()) |
| { |
| string data = client.DownloadString("https://example.com"); |
| Debug.WriteLine("下載完成,內容長度:" + data.Length); |
| } |
| }); |
| |
| Debug.WriteLine("主執行緒不中斷,繼續執行其他工作"); |
| } |
| } |
非同步排程(定時任務)
| using System; |
| using System.Threading.Tasks; |
| using System.Diagnostics; |
| |
| class Program |
| { |
| static void Main() |
| { |
| Debug.WriteLine("開始排程任務"); |
| |
| Task.Run(() => |
| { |
| while (true) |
| { |
| Debug.WriteLine("定時任務執行中:" + DateTime.Now); |
| Task.Delay(2000).Wait(); |
| } |
| }); |
| |
| Debug.WriteLine("主執行緒自由運作"); |
| } |
| } |
留言
張貼留言