當我們寫程式時,有時候需要「等一個外部動作」完成,例如:
如果用一般的同步程式,整個程式會在等待時「卡住」。
為了避免這種情況,我們可以用 非同步程式設計 (async/await)。
來看一個同步程式的例子:
using System;
using System.Threading;
class Program
{
static void Main()
{
Console.WriteLine("開始下載資料...");
Thread.Sleep(3000); // 模擬耗時 3 秒
Console.WriteLine("下載完成!");
}
}
執行時,畫面會停住 3 秒,才能繼續往下跑。
這在桌面應用程式(WPF)中會讓 UI 卡住,使用者無法操作。
C# 的非同步(asynchronous)主要是透過 async 與 await 關鍵字來實現,讓程式在遇到耗時的工作(例如 I/O 操作、網路請求、資料庫查詢)時,不會阻塞整個執行緒。
非同步方法 (async 方法)
async 關鍵字修飾。Task 或 Task<T>,若沒有回傳值則可以用 Task,特殊情況可以用 void(像事件處理函式)。等待工作完成 (await)
await 關鍵字會等待一個 Task 完成,但不會阻塞目前執行緒。背景工作與資源利用
C# 提供 Task 與 async/await 來處理非同步。
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("開始下載資料...");
await DownloadDataAsync();
Console.WriteLine("下載完成!");
}
static async Task DownloadDataAsync()
{
await Task.Delay(3000); // 模擬等待 3 秒
}
}
這裡有幾個重點:
Main 改成 async Task Main,允許使用 await。DownloadDataAsync 回傳 Task,代表它是非同步方法。await Task.Delay(3000) 模擬等待 3 秒,但程式不會「卡住 UI」。using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("準備下載股票清單...");
List<string> stocks = await GetStockListAsync();
Console.WriteLine("下載完成!");
foreach (var s in stocks)
{
Console.WriteLine(s);
}
}
static async Task<List<string>> GetStockListAsync()
{
await Task.Delay(2000); // 模擬網路延遲
return new List<string> { "2330 台積電", "2303 聯電", "2317 鴻海" };
}
}
執行時:
今天我們學會了:
Task、async、await 的基本用法參考資料:https://learn.microsoft.com/zh-tw/dotnet/csharp/asynchronous-programming/