10

例如,每当我等待某些东西时,编译器都会通知我包含方法必须是异步的。为什么没有以这种方式看到异步羔羊?如果 ForEach 隐藏了它,那么关于不返回 Task 对象和 ForEach 被隐式异步无效是否存在一些危险?

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

2 回答 2

12

异步 lambda 只是创建异步委托的一种简单方法。没有什么可以说包含它的方法必须自己做任何异步的事情——并且awaitlambda 表达式中的任何表达式都不会使包含方法等待(当然,除非它正在等待一个恰好依赖于委托的任务) .

基本上,lambda 表达式是在表达一些异步代码——它本身并不执行异步代码……所以包含方法不一定是异步执行的。

是的,您给出的示例是对 async lambda 的误用——但是使方法 async 根本不会改善问题,而且只会产生误导。

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

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方法没有任何异步 - 只有该SaveRepAsync方法......所以这就是需要async修饰符的原因。这实际上只是对代码的微小重构(编译器会有效地进行重构)。如果您希望每个包含 async lambda 的方法都具有 async 修饰符,这就像在上面的代码中说的那样,SaveSome也应该具有修饰符......这没有任何意义,IMO。

于 2013-09-12T11:48:31.297 回答
4

您只能awaitasync方法中使用async方法,但您仍然可以在非异步方法中调用它们,就像您在上面所做的那样 - 在这种情况下,它更像是“一劳永逸”

于 2013-09-12T11:49:21.277 回答