簡體   English   中英

當有多個任務同時完成時的Task.WaitAny

[英]Task.WaitAny when there are multiple tasks that finishes at the same time

我正在使用Task.WaitAny並傳入正在運行的任務數組。 如果有多個任務同時完成,我想知道如何捕獲所有已完成任務的索引。

例如,我正在檢索完成的任務的索引,如下所示:

int i = Task.WaitAny(taskArray);

使用索引i,我將數組中的該位置替換為另一個啟動的任務。 taskArray具有固定的長度,我只能啟動新任務,並在完成任務時替換陣列中的任務。 如果僅在Task.WaitAny()上返回一個索引,並且數組中的多個任務可能同時完成,該怎么辦。 如果僅返回一個索引,我該如何處理同時完成的其他任務?

`

如果僅返回一個索引,我該如何處理同時完成的其他任務?

需要明確的是:它是所有意圖和目的是不可能的,這可以從字面上是真實的,多個任務會在同一時間完成。 即使同時在單獨的CPU內核中運行,真正同時完成的可能性也基本為零。

因此,您真正要問的是競爭條件,其中一個任務完成,然后在對線程的WaitAny()調用返回到線程中並且調用方法中的后續代碼可以執行之前,一個或多個其他任務也已經完成。

您的問題缺少有關實際情況的詳細信息,但是通常您有兩種選擇:

  1. 掃描傳遞給WaitAny()taskArray ,以查找所有當前完成的任務。
  2. 再次調用WaitAny() ,使用所有先前傳遞的任務,除了您所了解的任務。

哪個更合適取決於您實際需要如何使用完成信息。 如果您只關心當前已完成的任務並希望立即處理它們,則第一種選擇是最好的。 如果您對有序的完成結果感興趣(例如,知道哪個任務以哪個順序完成),但又想立即繼續等待剩余的任務,則第二種選擇是最好的。

請注意,在第二個選項中,如果在再次調用WaitAny()之前完成了多個任務,則由於競爭條件,該順序有些隨意。 該條件由WaitAny()方法“解決”,它選擇將哪個任務作為剛剛完成的當前任務呈現給您。 但是,除非您在每個任務中維護自己的時間信息,否則您將無法確定哪個真正先完成。

如果以上內容未能充分解決您的問題,則需要改進您的問題,以便包括有關以上內容未能解決您的問題的完整詳細信息,以及您嘗試使用WaitAny()的完成方式的確切信息。方法。 確保包括一個良好的最小,完整和可驗證的代碼示例 ,以說明所有這些。


(此外:以上所有內容當然都忽略了是否應該使用WaitAny() 。通常最好使用WhenAny()異步等待。但是,存在相同的基本問題,並且不會改變答案,因此似乎很合理暫時不用擔心這種差異。)

任何任務都可以隨時完成。 當然,有可能同時完成兩個或更多任務。

但是,您無需擔心任何情況。 Task.WhenAny將返回已完成數組中一個任務的索引。 在索引處放置一個新任務, Task.WhenAny再次調用Task.WhenAny 如果數組中有任何已完成的任務,它將立即返回已完成任務之一的索引。

async Task Execute( IEnumerable<Func<Task>> taskFunctions, int maxParallel )
{
    var taskList = new List<Task>(maxParallel);
    foreach ( var taskFunc in taskFunctions )
    {
        var task = taskFunc();
        taskList.Add( task );
        if ( taskList.Count == maxParallel )
        {
            var idx = await Task.WhenAny( taskList ).ConfigureAwait(false);
            taskList.RemoveAt( idx );
        }
    }
    await Task.WhenAll( taskList ).ConfigureAwait(false);
}

暫無
暫無

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

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