iT邦幫忙

1

C#非同步和多執行緒併用

  • 分享至 

  • xImage

C#既可以寫非同步,也可以寫多執行緒,在想有沒有可以同時應用這兩者的情境:在不同的執行緒裡再加上非同步,達到更高效的資料處理能力?

試問各位有沒有將這兩者一起使用過的經驗? 又或者什麼情況下適合這樣用 、實務上這樣做的機會多嗎? 能否舉些例子,謝謝

froce iT邦大師 1 級 ‧ 2023-02-13 13:54:31 檢舉
https://stackoverflow.com/questions/27435284/multiprocessing-vs-multithreading-vs-asyncio

並用的場景像是併發的多執行緒爬蟲,或是單元/壓力測試。
https://ithelp.ithome.com.tw/questions/10211936
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

4
JamesDoge
iT邦高手 1 級 ‧ 2023-02-12 12:47:34
最佳解答

例子:
作為一個銀行系統的開發人員,我希望能夠同時處理大量的帳戶轉帳請求,以提高系統的效率和性能。為了實現這一目標,我將使用多執行緒和非同步編程。我會將大量的帳戶轉帳請求分成多個模組,並在多個執行緒中同時處理這些請求。同時,我將使用非同步處理,以確保每個執行緒都能同時處理多個請求,而不會阻塞執行緒。這樣,我可以實現高效的帳戶轉帳處理,並確保系統性能不會受到影響。

範例程式:

using System;
using System.Threading.Tasks; // 引用 Task 類

namespace BankTransferExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 創建 TransferManager 實例
            TransferManager transferManager = new TransferManager();
            // 執行轉帳請求的處理
            transferManager.ProcessTransfers();
            Console.ReadKey();
        }
    }

    public class TransferManager
    {
        // 定義一個 Account 類型的陣列,用於存儲帳戶訊息
        private Account[] accounts = new Account[10];

        public TransferManager()
        {
            // 初始化帳戶訊息
            for (int i = 0; i < accounts.Length; i++)
            {
                accounts[i] = new Account { AccountNumber = i, Balance = 1000 };
            }
        }

        public async void ProcessTransfers()
        {
            // 每個執行緒處理的帳戶塊數
            int blockSize = accounts.Length / 4;
            // 定義四個 Task 類型的陣列,分別用於儲存四個執行緒
            Task[] tasks = new Task[4];

            for (int i = 0; i < 4; i++)
            {
                // 計算當前執行緒處理的帳戶塊的起始索引和結束索引
                int startIndex = i * blockSize;
                int endIndex = (i + 1) * blockSize - 1;
                // 創建一個新的 Task 類型的對象,並在該對像中執行 ProcessBlock 方法
                tasks[i] = Task.Run(() => ProcessBlock(startIndex, endIndex));
            }

            // 等待所有 Task 對像完成
            await Task.WhenAll(tasks);
        }

        private async void ProcessBlock(int startIndex, int endIndex)
        {
            // 循環處理當前執行緒負責的帳戶塊中的每個帳戶
            for (int i = startIndex; i <= endIndex; i++)
            {
                // 執行轉帳操作
                await Transfer(accounts[i], accounts[i + 1], 100);
            }
        }

        private async Task Transfer(Account fromAccount, Account toAccount, double amount)
        {
            // 模擬轉帳操作的耗時
            await Task.Delay(100);
            // 更新轉出帳戶的餘額
            fromAccount.Balance -= amount;
            // 更新轉入帳戶的餘額
            toAccount.Balance += amount;
        }
    }

    public class Account
    {
        // 帳戶號碼
        public int AccountNumber { get; set; }
        // 帳戶餘額
        public double Balance { get; set; }
    }
}

僅供參考

WILL.I.AM iT邦新手 3 級 ‧ 2023-04-07 09:08:42 檢舉

謝謝你的範例

我要發表回答

立即登入回答