例如,每当我等待某些东西时,编译器都会通知我包含方法必须是异步的。为什么没有以这种方式看到异步羔羊?如果 ForEach 隐藏了它,那么关于不返回 Task 对象和 ForEach 被隐式异步无效是否存在一些危险?
public void SaveSome()
{
Array.ForEach(Enumerable.Range(0,3).ToArray(), async x => await SaveRep());
}
例如,每当我等待某些东西时,编译器都会通知我包含方法必须是异步的。为什么没有以这种方式看到异步羔羊?如果 ForEach 隐藏了它,那么关于不返回 Task 对象和 ForEach 被隐式异步无效是否存在一些危险?
public void SaveSome()
{
Array.ForEach(Enumerable.Range(0,3).ToArray(), async x => await SaveRep());
}
异步 lambda 只是创建异步委托的一种简单方法。没有什么可以说包含它的方法必须自己做任何异步的事情——并且await
lambda 表达式中的任何表达式都不会使包含方法等待(当然,除非它正在等待一个恰好依赖于委托的任务) .
基本上,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。
您只能await
在async
方法中使用async
方法,但您仍然可以在非异步方法中调用它们,就像您在上面所做的那样 - 在这种情况下,它更像是“一劳永逸”