簡體   English   中英

對多個異步調用的反應不同

[英]react different to multiple async calls

想象以下情況:

public async Task DoMultipleWork() {
    var uploadTask = UploadAsync(file);
    var processingTask = Task.Run( () => DoCpuWork() );

    await Task.WhenAll(uploadTask, processingTask);
    Console.WriteLine("upload is done");
    Console.WirteLine("processing is done");
}

我該如何更改該代碼,以便無論哪個先結束,它都會執行一些特定的(同步或異步)代碼。

因此,我同時啟動了兩個任務,當taskAtaskB結束時,我只是獨立於其他代碼運行了一些代碼(同步或異步)。

我想也許是ContinueWith但我不確定,因為它需要另一個並不需要的異步方法。

編輯正如對答案的評論所建議,我想清除一下我想根據完成的任務執行不同的代碼,並在原始任務完成后立即執行兩個Console.WriteLine。

您想使用Task.WhenAny返回返回的第一個任務。 然后,您可以通過與原始任務進行比較來判斷完成了哪個任務。 返回之前,您應該等待另一個明確完成(或使用Task.WhenAll都等待):

public async Task DoMultipleWork() 
{
    var uploadTask = UploadAsync(file);
    var processingTask = Task.Run( () => DoCpuWork() );

    var completedTask = await Task.WhenAny(uploadTask, processingTask);
    Console.WriteLine("upload or processing is done");
    if (completedTask == uploadTask)
    {
        // Upload completed
    }
    else
    {
        // Processing completed
    }

    await Task.WhenAll(uploadTask, processingTask) // Make sure both complete
    Console.WriteLine("upload and processing are done");
}

正如我在博客上所描述的那樣, 除非您明確傳遞了Scheduler,否則ContinueWith是危險的 在大約99%的情況下,您應該使用await而不是ContinueWith (更多詳細信息在另一篇博客文章中 )。

在您的情況下:

private async Task UploadAsync(string filepath)
{
  var result = await fileManager.UploadAsync(filepath);
  Console.WriteLine($"Result from uploading file {result}");
}

private async Task ProcessAsync(string filepath, IProgress<T> progress)
{
  await Task.Run(() => wordProcessor.Process(filepath, progress));
  Console.WriteLine("processing completed");
}

...

await Task.WhenAll(UploadAsync(filepath), ProcessAsync(filepath, processingProgress));
public async Task DoMultipleWork() {
var uploadTask = UploadAsync(file);
var processingTask = Task.Run( () => DoCpuWork() );

uploadTask.ContinueWith((Task t) => Console.WriteLine("YOUR_MESSAGE"), TaskContinuationOptions.OnlyOnRanToCompletion);

processingTask.ContinueWith((Task t) => Console.WriteLine("YOUR_MESSAGE"), TaskContinuationOptions.OnlyOnRanToCompletion);

await Task.WhenAll(new []{uploadTask, processingTask});

}

暫無
暫無

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

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