哈囉大家好!
今天要介紹在撰寫程式碼中很常用到的「非同步程式設計」(Asynchronous Programming)!
C#中的非同步程式設計(Asynchronous Programming),可以讓程式在執行時操作時,不必停下來等待結果,可以釋放執行緒(Thread)去處理其他的任務。
C# 透過async和await兩個關鍵字來撰寫非同步程式碼,稱為工作基礎非同步模式(Task-based Asynchronous Pattern)。
async
Task(沒有回傳值)或Task<T>(有回傳值T)來代表一個進行中的非同步操作。await
await時,如果該Task還沒有完成,程式會暫停function, 並將控制權交給caller,這時執行緒會被釋放。await之後的位置自動恢復執行。這裡我用「家庭主婦媽媽」來比喻執行緒(Thread)處理任務的過程:
1.同步(Synchronous)
有一位家庭主婦媽媽(一個執行緒),需要完成三項任務:洗衣服、烤土司、泡咖啡。
媽媽早上的任務流程如下:
Task啟動)Task啟動)角色名詞對應:
這裡用一個情境例子來練習:我要將log寫入特定文字檔中,要透過async function來提高應用程式的響應性(避免在寫入log時因為寫入大檔案或共享資料夾,同步設計造成UI介面暫時停止響應):
using System;
using System.IO;
using System.Threading;
public class LogProcessor
{
    private const string LogFilePath = "my_example_log.txt";
    public async Task WriteLogAsync(string message)
    {
        string logEntry = $"{DateTime.Now:HH:mm:ss} [Thread ID: {Thread.CurrentThread.ManagedThreadId}] - {message}";
        Console.WriteLine($"準備寫入日誌: {logEntry}");
        await Task.Delay(5000); // await 5秒
        await File.AppendAllTextAsync(LogFilePath, logEntry + Environment.NewLine);
        Console.WriteLine("日誌寫入完成");
    } 
}
public class Program
{
    public static async Task Main(string[] args)
    {
        LogProcessor processor = new LogProcessor();
        
        Console.WriteLine("main:啟動日誌寫入。");
        await processor.WriteLogAsync("使用者登入事件"); 
        Console.WriteLine("main:寫入完成,執行其他工作");
    }
}
程式執行流程如下:
await Task.Delay(5000)時,會把控制權返回給caller(Main function)>