← SEARCHABLE ARCHIVE
C# · 2026-08-07

C# 從基礎到精通 — 第 8 講

使用async和await建立非同步任務

INTERACTIVE READING MODE →

該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。

在等待網路或檔案操作時阻塞執行緒也可能凍結螢幕和其他操作。 async 和await 表示等待任務,以便可以連續執行。

返回任務

async Task<PlayerData> LoadPlayerAsync(
    string url,
    CancellationToken cancellationToken)
{
    using HttpResponseMessage response =
        await httpClient.GetAsync(url, cancellationToken);

    response.EnsureSuccessStatusCode();

    PlayerData? data = await response.Content
        .ReadFromJsonAsync<PlayerData>(cancellationToken);

    return data ?? throw new InvalidDataException("Player data is empty");
}

當您遇到等待時,您可以稍後繼續執行其餘程式碼,而不是保留當前執行緒直到任務完成。 非同步方法基本上會傳回一個任務,以便呼叫者可以觀察完成和失敗。

取消轉發

using var source = new CancellationTokenSource(TimeSpan.FromSeconds(5));

try
{
    PlayerData data = await LoadPlayerAsync(url, source.Token);
}
catch (OperationCanceledException)
{
    Console.WriteLine("Loading canceled");
}

Cancel 不是強制終止執行緒的函數。 請求任務驗證令牌並在安全點中止的合約。

等待多個任務

Task<ItemData> itemTask = LoadItemsAsync(token);
Task<QuestData> questTask = LoadQuestsAsync(token);

await Task.WhenAll(itemTask, questTask);

ItemData items = await itemTask;
QuestData quests = await questTask;

相互不依賴的等待任務可以先啟動,然後一起等待。 簡單地將 CPU 計算標記為非同步並不會自動使其並行計算。

避免流動

使用Task的.Result或.Wait()進行同步等待可能會阻塞執行緒或建立死鎖,具體取決於執行環境。 最好盡可能繼續異步呼叫路徑。

除事件處理程序外,應避免使用 async void,因為呼叫者無法等待完成和異常。 非同步程式碼的關鍵不是添加關鍵字,而是向呼叫者傳達完成、失敗和取消的流程。