2

我有一个具有以下结构的匿名 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() 函数内部,我使用Dropbox 的Spring.NET 社交扩展将大文件上传到 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() 的调用,以便代码同步执行,但我仍然无法捕获此异常。

4

1 回答 1

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;
            }
        }
    }
}

您可以在此处阅读有关异常处理和任务的信息。

于 2012-11-12T18:30:40.003 回答