iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0

當我們寫程式時,有時候需要「等一個外部動作」完成,例如:

  • 從 API 下載股票資料
  • 存取檔案或資料庫
  • 網路請求

如果用一般的同步程式,整個程式會在等待時「卡住」。
為了避免這種情況,我們可以用 非同步程式設計 (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)主要是透過 asyncawait 關鍵字來實現,讓程式在遇到耗時的工作(例如 I/O 操作、網路請求、資料庫查詢)時,不會阻塞整個執行緒。


核心概念

  1. 非同步方法 (async 方法)

    • 使用 async 關鍵字修飾。
    • 通常會回傳 TaskTask<T>,若沒有回傳值則可以用 Task,特殊情況可以用 void(像事件處理函式)。
  2. 等待工作完成 (await)

    • await 關鍵字會等待一個 Task 完成,但不會阻塞目前執行緒。
    • 在等待的同時,控制權會被還給呼叫端,讓系統能處理其他工作。
  3. 背景工作與資源利用

    • 適合處理耗時操作,例如下載檔案或呼叫 API。
    • 避免 GUI 卡住或伺服器 thread pool 被塞滿。

優點

  • 提升效能:允許多個 I/O 操作同時進行。
  • 更好的使用者體驗:UI 不會卡死。
  • 程式碼可讀性高:相比 callback 或 Thread,更直觀。

Task 與 async/await

C# 提供 Taskasync/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 秒
    }
}

這裡有幾個重點:

  1. Main 改成 async Task Main,允許使用 await
  2. DownloadDataAsync 回傳 Task,代表它是非同步方法。
  3. 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 鴻海" };
    }
}

執行時:

  1. 會立即顯示「準備下載股票清單...」
  2. 模擬等候 2 秒
  3. 顯示下載完成,並印出股票清單

小結

今天我們學會了:

  • 為什麼需要非同步:避免程式卡住
  • Taskasyncawait 的基本用法
  • 模擬下載股票資料的範例

參考資料:https://learn.microsoft.com/zh-tw/dotnet/csharp/asynchronous-programming/


上一篇
Day 10 - 例外處理 (Exception Handling)
系列文
30天快速上手製作WPF選股工具 — 從C#基礎到LiteDB與Web API整合11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言