C# 多執行緒程(Multithreading)【五】task

Task 是非同步程式設計(asynchronous programming)的一個核心概念,它代表一個非同步操作。

用來表示非同步工作的類別,實現非同步處理、平行運算、不阻塞 UI。

命名空間System.Threading.Tasks


在 C# 中常見的定義方式如下:

Task t = Task.Run(() => {
    // 一些要背景執行的工作
    Debug.WriteLine("背景執行的程式碼");
});

如果這個背景工作會傳回一個結果,例如整數,則會使用泛型版本 Task<T>

Task<int> t = Task.Run(() => {
    return 42;
});


非同步處理資料、不中斷主執行緒

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("主執行緒開始");

        Task.Run(() =>
        {
            Debug.WriteLine("資料處理開始");
            Thread.Sleep(2000); // 模擬資料處理
            Debug.WriteLine("資料處理完成");
        });

        // 主執行緒仍然可以繼續工作
        for (int i = 0; i < 5; i++)
        {
            Debug.WriteLine("主執行緒仍在執行中...");
            Thread.Sleep(500);
        }
        
        Debug.WriteLine("主執行緒結束");
    }
}
  • Task.Run(...):啟動一個新的非同步工作。
  • Thread.Sleep(...):模擬一個耗時的處理(例如存取資料庫、網路請求等)。
  • ContinueWith(...):當上面的任務完成後再執行。
  • task.Wait():主執行緒等待該 Task 完成,避免主程式提早結束。

非阻塞主執行緒

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("主執行緒開始");

        // 啟動一個非同步任務,不會阻塞主執行緒
        Task.Run(() =>
        {
            Debug.WriteLine("背景工作開始執行...");
            Thread.Sleep(3000); // 模擬耗時操作
            Debug.WriteLine("背景工作結束");
        })
        .ContinueWith(t =>
        {
            Debug.WriteLine("後續處理完成");
        });

        // 主執行緒繼續執行,不等待上面的任務
        for (int i = 0; i < 5; i++)
        {
            Debug.WriteLine($"主執行緒正在執行其他工作... {i}");
            Thread.Sleep(500);
        }

        Debug.WriteLine("主執行緒結束");
    }
}
  • 背景任務透過 Task.Run 執行
  • ContinueWith task結束後,可接後續任務執行

多個任務平行執行

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("主執行緒啟動");

        for (int i = 1; i <= 3; i++)
        {
            int taskNum = i;
            Task.Run(() =>
            {
                Debug.WriteLine($"Task {taskNum} 開始");
                Thread.Sleep(1000 * taskNum); // 模擬不同時間長度
                Debug.WriteLine($"Task {taskNum} 結束");
            });
        }

        Debug.WriteLine("主執行緒正在執行其他事");
    }
}

從非同步任務中回傳資料

雖然不能 await 結果,但你可以使用 ContinueWith 來處理結果。

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("主執行緒開始");

        Task task = Task.Run(() =>
        {
            Thread.Sleep(1500);
            return 42; // 模擬計算後回傳的資料
        });

        task.ContinueWith(t =>
        {
            Debug.WriteLine($"收到非同步結果:{t.Result}");
        });

        Debug.WriteLine("主執行緒繼續執行");
    }
}

模擬非同步下載

using System;
using System.Net;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("開始模擬下載");

        Task.Run(() =>
        {
            using (WebClient client = new WebClient())
            {
                string data = client.DownloadString("https://example.com");
                Debug.WriteLine("下載完成,內容長度:" + data.Length);
            }
        });

        Debug.WriteLine("主執行緒不中斷,繼續執行其他工作");
    }
}

非同步排程(定時任務)

using System;
using System.Threading.Tasks;
using System.Diagnostics;//for Debug.WriteLine

class Program
{
    static void Main()
    {
        Debug.WriteLine("開始排程任務");

        Task.Run(() =>
        {
            while (true)
            {
                Debug.WriteLine("定時任務執行中:" + DateTime.Now);
                Task.Delay(2000).Wait(); // 每 2 秒執行一次
            }
        });

        Debug.WriteLine("主執行緒自由運作");
    }
}

留言