簡體   English   中英

在C#中啟動數千個任務的最佳方法是什么?

[英]What is the best way to start thousands of Tasks in C#

假設我有一個用戶List ,我想對所有用戶執行一些操作,例如更新數據庫中的一個屬性。 用戶列表可能包含數十或數十萬用戶。 如果要對用戶完成的所有工作都是我的機器的本地工作,那么我只會使用Parallel.ForEach來處理它們,但是因為這將涉及等待(可能是幾秒鍾)來完成對外部服務的調用,我認為使用Task更合適。

現在,這是我的代碼:

        Task.WaitAll(usersList.Select(user => Task.Run(() => async
        {
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await UpdateUserInExternalService(user);
            }
            catch (Exception ex)
            {
                LogError($"Something went wrong with user 'user.Username'.", ex);
            }
        }, cancellationToken)).ToArray());

我有一些問題:

  1. 如果列表中有10,000個用戶,它是否實際上同時創建了10,000個任務(巨大的內存峰值)? 或者它只是創造,比方說10,然后當一些任務完成時其他任務被旋轉起來?
  2. 我是如何使用取消令牌看起來正確的?
  3. 如果我在調用它之后立即取消操作,它是否仍然需要在取消之前啟動所有10,000個任務,或者是否因為我將取消令牌傳遞給Task.Run參數而避免了?

在我的測試中它似乎運作良好。 我只是想確保沒有任何我忽略的東西或者我可能會遇到的一些問題,或者是否有一個我沒有遵循的最佳實踐。

我願意接受任何建議。 提前致謝。

更新

根據評論,我無法控制外部服務或其數據庫。 我只有他們提供給我的電話,這需要一個用戶。 謝謝。

是的,此代碼將立即啟動所有操作。 Task.Run做得不多。 由於這是使用異步IO,因此線程池幾乎沒有參與。 它不會限制它。

不要這樣做。 可能,這會使一些資源超載。 使用https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/中的最后一段代碼。 這樣的事情應該在框架中,因為幾乎總是有必要為IO工作選擇精確的並行度。

(3)修復后無關緊要。 在修復之前,令牌幾乎沒有任何影響,因為所有操作都立即啟動,導致令牌僅立即被檢查一次。 之后取消不再可能。

您還可以將令牌傳遞給UpdateUserInExternalService以實現更快速的取消。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM