为什么包含异步lambda的方法不需要是Async本身?

Jay*_*cee 8 c# lambda asynchronous c#-5.0

例如,每当我等待编译器通知我的内容时,包含的方法必须是Async.为什么这种方式看不到异步lamba?如果ForEach隐藏它,那么是否有一些关于不返回Task对象和ForEach隐式异步void的危险?

    public void SaveSome()
    {
        Array.ForEach(Enumerable.Range(0,3).ToArray(), async x =>  await SaveRep());
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 11

异步lambda只是创建异步委托的一种简单方法.没有什么可说的,包含它的方法本身必须做任何异步 - 而awaitlambda表达式中的任何表达式都不会使包含方法等待(除非它正在等待依赖于委托的任务,当然) .

基本上lambda表达式表示一些异步代码 - 它不执行异步代码本身...所以包含方法不一定异步执行.

是的,你给出的例子是滥用异步lambdas - 但是使方法异步并不会改善问题,而这只会产生误导.

编辑:作为另一种思考方式,请考虑重构原始代码:

public void SaveSome()
{
    Action<int> action = SaveRepAsync;
    Array.ForEach(Enumerable.Range(0,3).ToArray(), action);
}

private static async void SaveRepAsync(int x)
{
    await SaveRep();
}
Run Code Online (Sandbox Code Playgroud)

SaveSome方法没有任何异步 - 只有SaveRepAsync方法...这就是需要async修饰符的东西.这实际上只是对代码的一种微小重构(编译器将有效地进行重构).如果你想让每个包含异步lambda的方法都有async修饰符,就像在上面的代码中说的那样,也SaveSome应该有修饰符......这对IMO来说没有意义.

  • @Jaycee:好吧,您正在调用`Array.ForEach`,它通常会按顺序执行操作-但是您的异步​​ lambda *只是* 等待其他操作。你实际上只是在做一个即发即弃的操作,但没有任何迹象表明一切何时完成。如果你*真的*想要一种完全一劳永逸的方法,我个人会选择一种不同的表达方式。就 `Array.ForEach` 而言,它只是被赋予了一个 `Action&lt;int&gt;`。 (2认同)