C# 对多个异步调用做出不同的反应

C# 对多个异步调用做出不同的反应,c#,asynchronous,async-await,C#,Asynchronous,Async Await,想象一下以下场景: public async Task DoMultipleWork() { var uploadTask = UploadAsync(file); var processingTask = Task.Run( () => DoCpuWork() ); await Task.WhenAll(uploadTask, processingTask); Console.WriteLine("upload is done"); Consol

想象一下以下场景:

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");
}
我怎样才能更改代码,使它不必管哪一个先结束,而是执行一些特定的(同步或异步)代码

因此,我启动这两个任务,当
taskA
taskB
结束时,我只运行一些独立于另一个的代码(同步或异步)

我想可能是
继续使用
,但我不确定,因为它需要另一种不需要的异步方法

编辑
正如在answer上的评论所建议的,我想明确我希望根据完成的任务执行不同的代码,并在原始任务完成后立即执行Console.WriteLine。

您希望使用返回第一个完成的任务的
task.WhenAny
。然后,您可以通过与原始任务进行比较来判断完成了哪些任务。返回之前,您应该等待另一个任务显式完成(或者使用
任务等待这两个任务。whalll
):

正如我在博客上描述的那样。在大约99%的情况下,您应该使用
wait
而不是
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));
private async Task UploadAsync(字符串文件路径)
{
var result=await fileManager.UploadAsync(文件路径);
WriteLine($“上传文件的结果{Result}”);
}
专用异步任务进程异步(字符串文件路径,IProgress进程)
{
wait Task.Run(()=>wordProcessor.Process(filepath,progress));
Console.WriteLine(“处理完成”);
}
...
wait Task.WhenAll(UploadAsync(filepath)、ProcessAsync(filepath、processingProgress));

我会使用ContinueWith和ContinueWith任务,然后使用whalll。@EliAlgranti ContinueWith基于什么?@EliAlgranti我更喜欢
ContinueWith
的语法糖,但是要执行的代码不一定是异步的,看起来像
ContinueWith
需要异步的。是吗?@Bart又问了一遍,
继续写什么?您需要一个在任一任务之后运行的continue…是的,continue with将是另一个任务,并且不一定与“main”任务在同一线程中运行,而是“main”第一次调用wait时,任务被分派到第四行的任务队列,因此我认为线程关联性在这里不是问题。为什么
TaskContinuationOptions.notanrantocompletion
?很好,什么是非自动完成?根据您的需要,您也可以使用None,但绝对不是输入错误。我宁愿将
WaitAll
更改为
WhenAll
,这样您就不会阻塞线程,特别是针对这个问题的进一步读者。@Brat,我用WhenAll更改了它
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});

}
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));