我有以下情况:
foreach(var item in collection)
{
DoWork().Wait;
}
正如您所看到的,有一个foreach迭代一个集合,对于每个调用我需要等待DoWork
完成执行,之后foreach可以继续。
问题在于DoWork
我正在使用Parallel
并且我得到一个异常“冻结”程序,特别是没有显示任何异常,这是我的实现:
public async Task DoWork()
{
Try
{
Parallel.Invoke(
() => Foo(),
() => Foo2(),
() => Foo3());
}
catch(Exception e)
{
//No exception caught
}
}
我在Foo
方法内添加了Console.WriteLine
,例如:
public void Foo()
{
Console.WriteLine("foo 1");
}
在方法Foo2
内部生成了一个异常,但是我无法看到哪个异常,因为我在catch
上设置了一个断点并且没有触发。
我做错了什么?
答案 0 :(得分:4)
DoWork()
方法不会异步运行,因为它没有任何调用
到await
。无论如何,如果您想让DoWork()
正确异步,您需要使用Task.Run()
和await Task.WhenAll()
,如下所示:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
public static async Task Main()
{
Console.WriteLine("Awaiting DoWork()");
await DoWork();
Console.WriteLine("Finished awaiting. Press <RETURN> to exit.");
Console.ReadLine();
}
public static async Task DoWork()
{
try
{
await Task.WhenAll(
Task.Run(() => Foo()),
Task.Run(() => Foo2()),
Task.Run(() => Foo3())
);
}
catch (Exception e)
{
Console.WriteLine("Caught exception: " + e.Message);
}
}
public static void Foo()
{
Console.WriteLine("Starting Foo()");
Thread.Sleep(1000);
Console.WriteLine("Finishing Foo()");
}
public static void Foo2()
{
Console.WriteLine("Starting Foo2()");
Thread.Sleep(500);
Console.WriteLine("Foo2() is throwing an exception.");
throw new InvalidOperationException("OOPS!");
}
public static void Foo3()
{
Console.WriteLine("Starting Foo3()");
Thread.Sleep(250);
Console.WriteLine("Finishing Foo3()");
}
}
}
如果编译并运行该代码,您将看到以下消息:
waiting DoWork()
Starting Foo()
Starting Foo2()
Starting Foo3()
Finishing Foo3()
Foo2() is throwing an exception.
Finishing Foo()
Caught exception: OOPS!
Finished awaiting. Press <RETURN> to exit.
请注意,此答案仅适用于C#7.1或更新版 Async Main