等待/异步并跳出框外

mmi*_*mix 5 .net c# multithreading asynchronous async-await

我有一个关于await/async的问题,并且在与预期稍有不同的场景中使用异步方法,例如没有直接等待它们.例如,让我们说我需要并行完成两个例程,其中两个都是异步方法(它们在内部等待).我正在使用await TAsk.WhenAll(...)它反过来期望某种任务列表等待.我做的是这样的:

            await Task.WhenAll(new Task[]
            { 
                Task.Run(async () => await internalLoadAllEmailTargets()),
                Task.Run(async () => await internalEnumerateInvoices())
            });
Run Code Online (Sandbox Code Playgroud)

这似乎对我来说过于复杂,因为我正在创建异步任务,其唯一目的是调用另一个任务.我不能只使用从异步方法状态引擎返回的任务吗?然而,我没有这样做,因为编译器将每个直接提到的异步方法都视为一个调用点:

            // this doesn't seem to work ok
            await Task.WhenAll(new Task[]
            { 
                internalLoadAllEmailTargets(),
                internalEnumerateInvoices()
            }); 
Run Code Online (Sandbox Code Playgroud)

如果像这样,它似乎一个接一个地同步调用,如果我等待在方法前面,它就不再是一个任务.是否有关于如何在普通等待之外处理异步方法的规则书?

Ste*_*ary 7

每个async方法都开始同步执行,但是当它遇到第一个时await,它可能表现为异步.所以这一行:

await Task.WhenAll(internalLoadAllEmailTargetsAsync(), internalEnumerateInvoicesAsync());
Run Code Online (Sandbox Code Playgroud)

应该工作得很好.它大致相当于:

var _1 = internalLoadAllEmailTargetsAsync();
var _2 = internalEnumerateInvoicesAsync();
await Task.WhenAll(_1, _2);
Run Code Online (Sandbox Code Playgroud)

如果你的方法是真正的异步,那么这应该没问题.

现在,如果您的方法实际上正在进行一些同步工作 - 比如,繁重的CPU绑定代码 - 那么您可能希望用它Task.Run来调用它们(如果您的调用代码在UI线程上).