想象一下,我有一个具有相同异步方法的类的列表,我可以在列表上分别进行操作:
public async Task Test()
{
foreach (var runner in _runners)
{
await runner.Test();
}
}
但我也可以:
public void Test()
{
_runners.ForEach(async runner => await runner.Test());
}
在这种情况下,不再需要我的测试方法是异步的。 但是这两种方法会产生相同的效果吗?
答案 0 :(得分:1)
据我所知,相当于您编写的代码(异步运行程序=>等待运行程序.Test())将是
public static async void Do(Runner r)
{
await r.Test();
}
因此,您不会等待Do方法(它是异步void),而在第一个版本中,您实际上仅在上一个结束之后才执行下一个任务。
我的测试方法不再需要异步
我认为它看起来像是因为在任何地方都没有显式的异步void,如果您使用命名方法重写它,将会更容易看到。
答案 1 :(得分:1)
区别是:
您可以等待第一种情况下返回的任务,第二种情况下等待“解雇”:
public async void TestCaller()
{
await Test();
// do things after all runners completed
}
调用async void
方法时,您必须自己处理异常,否则异常将被吞没。您将重写第二种情况,例如:
public void Test()
{
_runners.ForEach(async runner => {
try { await runner.Test(); }
catch (Exception e) { Console.Writeln(e.ToString()); }
});
}
看起来不太好。
在第一种情况下,每个任务都等待上一个任务的开始,而在第二种情况下,则不是(感谢Scott Chamberlain在评论中纠正了我)。