我一直在学习使用TPL,但我从这个article收集的例子中遇到了问题。我完全按照Task.Run示例中的方式复制并粘贴代码,但收到一条错误消息,说明未处理异常:
private async void button1_Click(object sender, EventArgs e)
{
try
{
await Task.Run(() =>
{
Thread.Sleep(1000);
throw new InvalidOperationException("Hi!");
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
这是错误的图片:
此代码示例是否已过时或是否遗漏了某些内容?
答案 0 :(得分:5)
这只是一个误导性的调试器消息。
实际发生的是异常被抛出,然后被.NET框架(不是用户代码)捕获,然后被放置在任务上。
因此,虽然技术上错误消息是正确的(它被.NET框架捕获 - 未被用户代码处理),但在这种情况下它并不是很有用。
不幸的是,调试器也没有很多替代方案。在异常离开用户代码时,调试器无法“展望未来”以了解异常将放在特定任务上,并且您的代码将await
该任务。它必须立即决定是否通知您,而不知道该任务是否await
。
答案 1 :(得分:0)
如Stephen的正确答案中所述,只有在调试器打开时才会发生这种情况。使用此简单的解决方法,您可以将Task.Run();之外的异常重新抛出。
Exception exceptionOut = null;
await Task.Run(() =>
{
try
{
// Your code
}
catch (Exception exceptionIn)
{
exceptionOut = exceptionIn;
}
});
if (exceptionOut != null)
throw exceptionOut;
答案 2 :(得分:-1)
您的try / catch运行异步操作,因此不保持异步操作,因为在命中异常时不保证代码位于该位置。尝试在Task.Run(() => {..});