簡體   English   中英

不等待所有任務是否安全

[英]Is it safe not to wait for all tasks

假設我有以下操作方法:

[HttpPost]
public async Task<IActionResult> PostCall()
{
    var tasks = new List<Task<bool>>();
    for (int i = 0; i < 10; i++)
        tasks.Add(Manager.SomeMethodAsync(i));

    // Is this line necessary to ensure that all tasks will finish successfully?
    Task.WaitAll(tasks.ToArray());

    if (tasks.Exists(x => x.Result))
        return new ObjectResult("At least one task returned true");
    else
        return new ObjectResult("No tasks returned true");
}

Task.WaitAll(tasks.ToArray())必須確保所有任務都能成功完成? Exists 無法訪問其Result的任務是否會成功完成后台執行? 或者有些任務(沒有等待)會被刪除,因為它們不會附加到請求中嗎? 有沒有更好的實施我錯過了?

是的,除非等待它們(等待等待的東西),否則不保證任務完成

在您的情況下,您應該進行的主要更改是創建Task.WaitAll

await Task.WhenAll(tasks);

所以它實際上是異步的。 如果你只是想等待一個任務返回,使用WhenAny代替。

在您提供的實現下, Task.WaitAll調用阻止調用線程,直到所有任務都完成。 它只會進入下一行,並在發生這種情況后執行Exists檢查。 如果刪除Task.WaitAll ,則Exists檢查將導致調用線程按順序阻塞每個任務; 即它首先阻止tasks[0] ; 如果返回false,則會阻塞tasks[1] ,然后阻塞tasks[2] ,依此類推。 這是不可取的,因為如果任務完成無序,它不允許您的方法提前完成。

如果您只需要等到任何一個任務首先返回true,那么您可以使用Task.WhenAny 這將使任何任務完成后您的異步方法恢復。 然后,您可以檢查它是否評估為true並立即返回成功; 否則,您將繼續重復剩余任務集的過程,直到沒有剩余任務為止。

如果您的代碼作為應用程序(WPF,WinForms,Console)運行,那么剩余的任務將繼續在線程池上運行直到完成,除非應用程序關閉。 線程池線程是后台線程,因此如果所有前台線程都已終止(例如因為所有窗口都已關閉),它們將不會使進程保持活動狀態。

由於您運行的是Web應用程序,因此您可能會在任務完成之前回收應用程序池。 未完成的任務是即發即棄的,因此運行時未被跟蹤。 為了防止這種情況發生,您可以通過HostingEnvironment.QueueBackgroundWorkItem方法在運行時注冊它們,如注釋中所示。

[HttpPost]
public async Task<IActionResult> PostCall()
{
    var tasks = Enumerable
        .Range(0, 10)
        .Select(Manager.SomeMethodAsync)
        .ToList();

    foreach (var task in tasks)
        HostingEnvironment.QueueBackgroundWorkItem(_ => task);

    while (tasks.Any())
    {
        var readyTask = await Task.WhenAny(tasks);
        tasks.Remove(readyTask);
        if (await readyTask)
            return new ObjectResult("At least one task returned true");
    }

    return new ObjectResult("No tasks returned true");
}

暫無
暫無

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

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