當我們寫程式時,有時候需要「等一個外部動作」完成,例如:
如果用一般的同步程式,整個程式會在等待時「卡住」。
為了避免這種情況,我們可以用 非同步程式設計 (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/