C# 异步void lambda表达式

C# 异步void lambda表达式,c#,async-await,generic-lambda,C#,Async Await,Generic Lambda,一个快捷键会告诉您尽可能避免使用async void myMethod()方法。在很多情况下,都是这样。我的问题基本上是这个最佳实践的一个分支: 下面的lambda表达式的计算结果是什么 Task.Run( async ()=> await Task.Delay(1000)); 如果它成为一个异步任务,那么我们将遵循最佳实践 但是如果它的计算结果为async void?是的,它的计算结果为async Task,因为Task.Delay(n)的返回类型为Task。因此,这是一种良好的做法

一个快捷键会告诉您尽可能避免使用
async void myMethod()
方法。在很多情况下,都是这样。我的问题基本上是这个最佳实践的一个分支:

下面的lambda表达式的计算结果是什么

Task.Run( async ()=> await Task.Delay(1000));
如果它成为一个
异步任务
,那么我们将遵循最佳实践


但是如果它的计算结果为
async void

是的,它的计算结果为
async Task
,因为
Task.Delay(n)
的返回类型为
Task
。因此,这是一种良好的做法

:

因此,上述代码可以缩短为:

public Form1()
{
    InitializeComponent();
    button1.Click += async (sender, e) =>
    {
        await Task.Delay(1000);
        textBox1.Text += "\r\nControl returned to Click event handler.\n";
        };
    }
}
现在缩短的代码看起来像您的代码。

对于表达式,lambdas说

表达式lambda返回表达式的结果

因此,例如,
()=>“hi”
返回一个字符串,即使没有
return
语句。但是如果表达式没有返回任何内容,比如在
()=>Console.WriteLine(“hi”)
中,那么它被认为是
无效的

然而,
async
lambdas有一点小技巧。表达式
wait Task.Delay(1000)
本身并没有返回任何内容。但是,该语言可以发现,如果您有一个
async
lambda,您可能希望它返回一个
任务
。因此,它更愿意这样做

因此:

Task.Run(async () => await Task.Delay(1000));
如果要使用命名方法表示,则与此等效:

private async Task Wait1000() {
    await Task.Delay(1000);
}
Task.Run(Wait1000);
但需要注意的是,
async
lambda可以推断为
async void
。这里认为它是
异步任务
的唯一原因是
Task.Run
。如果唯一可用的重载包含一个参数,那么它将被推断为
async void
,而不会向您发出任何警告

例如,这不会产生错误,并且lambda被视为
异步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
所以在使用它的地方要小心。您可以始终将鼠标悬停在方法名称上(如
任务中的
运行
。运行
),Visual Studio将告诉您它推断出的重载:


似乎有一些解释。在您的特定情况下,它将解析为一个异步函数,返回一个
任务
,因此遵循最佳实践。回答好,图片好,cows很棒。
private void RunThisAction(Action action) {
    action();
}
private async Task Wait1000() {
    await Task.Delay(1000);
}
RunThisAction(Wait1000); // 'Task Wait1000()' has the wrong return type