异步void Lambda表达式 [英] Async void lambda expressions
问题描述
快速的 Google搜索会告诉您避免在可能的情况下使用async void myMethod()
方法.在许多情况下,使其成为可能的方式.我的问题基本上是此最佳做法的分支:
A quick google search will tell you to avoid using async void myMethod()
methods when possible. And in many cases there are ways to make it possible. My question is basically an offshoot of this best practice:
以下lambda表达式的计算结果是什么?
What does the lambda expression below evaluate to?
Task.Run( async ()=> await Task.Delay(1000));
如果它成为async Task
,那么我们将遵循最佳实践.
If it becomes an async Task
then we are following best practice.
但是如果评估结果为async void
怎么办?
But what if it evaluates to async void
?
推荐答案
lambda表达式返回表达式的结果
An expression lambda returns the result of the expression 因此,例如,即使没有 So, for example, 但是 However there is a bit of trickery with 所以这个: 如果您要使用命名方法表示它,则等同于此: Is equivalent to this, if you were to express it with a named method: 但是必须注意,可以将 But it is important to note that 例如,这不会产生错误,并且lambda被视为 For example, this produces no error and the lambda is treated as 与您将其传递给名为 That is different than if you passed it a named 因此请小心在何处使用它.您总是可以将鼠标悬停在方法名称上(例如 So be careful where you use it. You can always hover over the method name (like the 这篇关于异步void Lambda表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
return
语句,() => "hi"
也会返回字符串.但是,如果表达式不返回任何内容(如() => Console.WriteLine("hi")
中的内容),则将其视为void
.() => "hi"
returns a string, even though there is no return
statement. But if the expression doesn't return anything, like in () => Console.WriteLine("hi")
, then it's considered void
.async
lambdas有一些诡计.表达式await Task.Delay(1000)
本身并不真正返回任何内容.但是,该语言可以弄清楚,如果您有一个async
lambda,则可能希望它返回一个Task
.因此,它会更喜欢.async
lambdas. The expression await Task.Delay(1000)
doesn't really return anything in itself. However, the language can figure out that if you have an async
lambda, you likely want it to return a Task
. So it will prefer that.Task.Run(async () => await Task.Delay(1000));
private async Task Wait1000() {
await Task.Delay(1000);
}
Task.Run(Wait1000);
async
lambdas 推断为async void
.在此处被认为是async Task
的唯一原因是因为Task.Run
Func<Task>
具有重载.如果唯一可用的重载采用了 Action
参数,那么它将被推断为async void
,而不会向您发出任何警告.async
lambdas can be inferred to be async void
. The only reason it is considered async Task
here is because Task.Run
has an overload for Func<Task>
. If the only available overload took an Action
parameter, then it would be inferred to be async void
, without any warning to you.async void
:async void
:private void RunThisAction(Action action) {
action();
}
RunThisAction(async () => await Task.Delay(1000));
async Task
的方法不同,这将导致编译器错误:async Task
method, which would cause a compiler error:private void RunThisAction(Action action) {
action();
}
private async Task Wait1000() {
await Task.Delay(1000);
}
RunThisAction(Wait1000); // 'Task Wait1000()' has the wrong return type
Task.Run
中的Run
),Visual Studio会告诉您它推断出了哪个重载:Run
in Task.Run
) and Visual Studio will tell you which overload it has inferred: