2012-11-12 30 views
1

我有一個匿名的TPL任務結構如下:不能趕上System.Reflection.TargetInvocationException(使用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塊,但它再也不會觸發。

所以我的問題是 - 我如何捕獲這個異常,爲什麼它不被上面的代碼中顯示的構造捕獲?

UPDATE:

這個問題似乎什麼都沒有做與TPL畢竟。我修改了調用來移除對StartNew()的調用,以便代碼同步執行,並且我仍然無法捕獲此異常。

+0

你的DoStuff調用中有什麼?也許Sprint.NET的實現是在一個完全獨立的線程中打開它? –

回答

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關於異常處理和任務。

+0

但我不調用task.Wait(),也不希望。在我的DoStuff()方法中,我等待其他異步任務完成。在調試器下運行時,拋出此異常時,我從不從DoStuff()方法返回。 –