[英]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()
調用返回到線程中並且調用方法中的后續代碼可以執行之前,一個或多個其他任務也已經完成。
您的問題缺少有關實際情況的詳細信息,但是通常您有兩種選擇:
WaitAny()
的taskArray
,以查找所有當前完成的任務。 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.