[英]C# How to remove a completed Task from Task[]
我有一個這樣運行的任務數組:(數組中的任務數不固定為 2,它可能會不時變化)。
Task[] templates = new Task[2] {
Task.Factory.StartNew( () => { x.foo(); }),
Task.Factory.StartNew( () => { y.bar(); })
};
然后我等待他們中的任何一個完成。
int taskID;
taskID = Task.WaitAny(templates);
任務完成后,我會檢查對象內的各種參數(x 或 y),如果沒有得到預期的結果,我想從模板數組中刪除已完成的任務。 像這樣的東西
template[taskID].RemoveThisTaskFromArray() // This is pseudo code to describe what I want.
taskID = Task.WaitAny(templates);
我將在循環中執行此操作,直到任務數組template[]
為空,或者我決定中止操作並退出循環。
int taskID;
do {
taskID = Task.WaitAny(templates);
if(template[taskID].valid == true) { // <-- example of test for success
// stop the remaining task in the template[] array.
break;
}
// remove the completed task so we can use WaitAany() again.
} while (template.Length > 0);
似乎Task[]
不支持數組成員,所以沒有Task[].RemoveAt()
函數。 我希望你明白我的意思。 有什么辦法可以解決這個問題?
只需使用List<Task>
代替。 而且,出於此處詳細描述的原因,請使用Task.Run
而不是Task.Factory.StartNew
。
var templates = new List<Task> {
Task.Run( () => { x.foo(); }),
Task.Run( () => { y.bar(); })
};
int taskID;
do {
taskID = Task.WaitAny(templates.ToArray());
if(templates[taskID].valid == true) { // <-- example of test for success
// stop the remaining task in the template[] array.
break;
}
templates.RemoveAt(taskID);
} while (template.Count > 0);
這將調用.ToArray()
,它將創建一個新數組(保留順序),因此效率稍低,但它有效。 這確實是為Task.WaitAll
提供它正在尋找的數組的最簡單方法,同時保留您輕松刪除項目的能力。
但我不知道你想用template[taskID].valid
做什么。 您是要使用templates
(帶有“s”)數組嗎? (這就是我的假設)但Task
沒有任何名為valid
屬性。 您是要查看Status
屬性嗎?
但是,您可以考慮使用async
和await
並使用Task.WhenAny
以避免在等待時阻塞當前線程。 Task.WhenAll
也接受任何IEnumerable
,所以你不需要調用.ToArray()
。
do {
var doneTask = await Task.WhenAny(templates);
// This will return any result, but also throw any exception that
// might have happened inside the task.
await doneTask;
templates.Remove(doneTask);
} while (templates.Count > 0);
有一些關於異步編程的文章寫得非常好,從這里開始: 使用 async 和 await 的異步編程
可以像這樣使用 linq 從任務列表中刪除已完成的任務
templates.RemoveAll(x => x.IsCompleted);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.