我有一个具有以下结构的匿名TPL任务:
Task.Factory.StartNew(() =>
{
try
{
DoStuff();
}
catch (OperationCanceledException ex)
{
// process cancellation
}
catch (Exception ex)
{
// process (log) all exceptions
}
finally
{
// tie up various loose ends
}
},
myCancellationToken, // cancellation token
TaskCreationOptions.LongRunning, // always create a new thread
TaskScheduler.Default // default task scheduler
);
在DoStuff()函数内部,我使用Spring.NET Social extension for Dropbox将大文件上传到Dropbox。由于某种原因我还不明白,在文件上传过程中会产生异常(通过UploadFileAsync()方法调用):
(System.Net.Sockets.SocketException (0x80004005): An established connection was aborted by the software in your host machine).
我仍然在研究为什么会发生这种异常,但这不是我关注礼物的部分。更大的问题是异常最终被包裹起来 System.Reflection.TargetInvocationException和一些奇怪的原因,我的try / catch块(在我的原始代码片段中)没有捕获它。
由于我无法捕获异常,它最终会崩溃应用程序。
虽然我认为没有必要,但我甚至尝试为TargetInvocationException添加一个显式的catch块,但它再也不会触发。
所以我的问题是 - 如何捕获此异常,为什么它不会被上面代码中显示的构造捕获?
更新
这个问题似乎与TPL无关。我修改了调用以删除对StartNew()的调用,以便代码同步执行,我仍然无法捕获此异常。
答案 0 :(得分:1)
我使用此代码验证是否可以捕获TargetInvocationException:
[Test]
public void TaskExceptionTest()
{
var task = Task.Factory.StartNew(
() =>
{
try
{
throw new TargetInvocationException(null);
}
catch (Exception e)
{
Console.WriteLine("Caught one (inside):" + e.GetType().Name);
}
});
try
{
task.Wait();
}
catch (AggregateException ae)
{
// Assume we know what's going on with this particular exception.
// Rethrow anything else. AggregateException.Handle provides
// another way to express this. See later example.
foreach (var e in ae.InnerExceptions)
{
if (e is TargetInvocationException)
{
Console.WriteLine("After:" + e.GetType().Name);
}
else
{
throw;
}
}
}
}
您可以阅读有关异常处理和任务的here。