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

时间:2013-09-12 11:44:48

标签: c# asynchronous lambda c#-5.0

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

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

2 个答案:

答案 0 :(得分:10)

异步lambda只是创建异步委托的一种简单方法。没有什么可以说包含它的方法必须是任何异步本身 - 并且lambda表达式中的任何await表达式都不会使包含方法等待(除非它等待一个当然,碰巧依赖代表的任务。

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

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

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

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

private static async void SaveRepAsync(int x)
{
    await SaveRep();
}

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

答案 1 :(得分:2)

await方法中只能async async方法,但仍然可以用非异步方式调用,就像你'重新做上面 - 在这种情况下,它更像是“火与忘记”