簡體   English   中英

如何確保任務已啟動並安全啟動?

[英]How to make sure a task is started and safely start it if not?

我從我無法控制的地方得到IEnumerable<Task> tasks 我不知道這些任務是否是使用new TaskTask.Run手動創建的,或者它們是否是異步方法調用async Task DoSomethingAsync()

如果我確實await Task.WhenAll(tasks) ,則可能會無限期掛起,因為可能沒有啟動一個或多個任務。

我不能執行tasks.ForEach(t => t.Start()) ,因為如果來自異步方法調用(已經啟動),我將收到InvalidOperationException“ tasks.ForEach(t => t.Start())風格的任務可能不會調用Start” 。

我不能await Task.WhenAll(tasks.Select(t => Task.Run(async () => await t)))因為每個t仍然不只是通過等待而開始。

我認為該解決方案與基於此檢查每個任務的StatusStart()有關,但我也認為它可能很棘手,因為該狀態隨時可能更改,對嗎? 如果這仍然是路要走,應該檢查哪些狀態正確,我應該擔心哪些線程問題?

非工作案例示例:

//making an IEnumerable as an example, remember I don't control this part
Task t = new Task( () => Console.WriteLine("started"));
IEnumerable<Task> tasks = new[] {t};

//here I receive the tasks
await Task.WhenAll(tasks);//waits forever because t is not started

工作案例示例:

//calls the async function, starting it.
Task t = DoSomethingAsync();
IEnumerable<Task> tasks = new[] {t};

//here I receive the tasks and it will complete because the task is already started
await Task.WhenAll(tasks);

async Task DoSomethingAsync() => Console.WriteLine("started");

如果由於某種原因您無法將代碼更改為不返回未啟動的任務,則可以檢查“ Status並啟動任務,如果它具有“已Created狀態:

if (task.Status == TaskStatus.Created)
   task.Start();

所有其他任務狀態均指示任務已完成,正在運行或正在計划中,因此您無需在該狀態下啟動任務。

當然,從理論上講,這會引入競爭條件,因為可以在檢查和Start呼叫之間直接開始任務,但是正如Servy在注釋中正確指出的(如果此處存在競爭條件),這意味着另一方(創建了該任務) 正在嘗試啟動它。 即使您處理異常( InvalidOperationException )-另一方也不太可能這樣做,因此在嘗試啟動自己的任務時也會獲得異常。 因此,只有一方(您或創建該任務的代碼)應嘗試啟動它。

就是說-比這樣做要好得多,因為要確保您永遠不會遇到未啟動的任務,因為將這樣的任務返回到外部代碼是很糟糕的設計,至少沒有明確指出(雖然在某些用例中可以在內部使用未啟動的任務)。

暫無
暫無

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

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