快速google search会告诉你避免使用 async void myMethod()
可能的方法。并且在很多情况下有 ways to make it possible .我的问题基本上是这个最佳实践的一个分支:
下面的 lambda 表达式的计算结果是什么?
Task.Run( async ()=> await Task.Delay(1000));
如果它变成
async Task
那么我们正在遵循最佳实践。但是如果它评估为
async void
呢? ?
最佳答案
The documentation对于表达式 lambdas 说,
An expression lambda returns the result of the expression
因此,例如,
() => "hi"
返回一个字符串,即使没有 return
陈述。但是如果表达式没有返回任何东西,比如 () => Console.WriteLine("hi")
, 那么它被认为是 void
.然而,
async
有一些技巧。 lambda 。表达式 await Task.Delay(1000)
本身并没有真正返回任何东西。但是,如果您有 async
,语言可以计算出lambda,您可能希望它返回 Task
.所以它会更喜欢那个。所以这:
Task.Run(async () => await Task.Delay(1000));
等价于这个,如果你用一个命名方法来表达它:
private async Task Wait1000() {
await Task.Delay(1000);
}
Task.Run(Wait1000);
但需要注意的是
async
lambda 表达式可以推断为 async void
.它被认为是唯一的原因 async Task
这是因为 Task.Run
has an overload for Func<Task>
.如果唯一可用的过载采用 Action
参数,则推断为 async void
,对你没有任何警告。例如,这不会产生错误并且 lambda 被视为
async void
:private void RunThisAction(Action action) {
action();
}
RunThisAction(async () => await Task.Delay(1000));
这与传递一个命名的
async Task
不同。方法,这会导致编译器错误:private void RunThisAction(Action action) {
action();
}
private async Task Wait1000() {
await Task.Delay(1000);
}
RunThisAction(Wait1000); // 'Task Wait1000()' has the wrong return type
所以在你使用它的地方要小心。您始终可以将鼠标悬停在方法名称上(如
Run
中的 Task.Run
),Visual Studio 会告诉您它推断出的重载:关于c# - 异步 void lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61827597/