2013-08-06 50 views
39

當調試器連接到.NET進程時,它(通常)在引發未處理的異常時停止。調試器沒有在異步方法中異常中斷/停止

但是,當您處於async方法中時,這似乎不起作用。

之前在下面的代碼中列出我已經試過的情景:

class Program 
{ 
    static void Main() 
    { 
     // Debugger stopps correctly 
     Task.Run(() => SyncOp()); 

     // Debugger doesn't stop 
     Task.Run(async() => SyncOp()); 

     // Debugger doesn't stop 
     Task.Run((Func<Task>)AsyncTaskOp); 

     // Debugger stops on "Wait()" with "AggregateException" 
     Task.Run(() => AsyncTaskOp().Wait()); 

     // Throws "Exceptions was unhandled by user code" on "await" 
     Task.Run(() => AsyncVoidOp()); 

     Thread.Sleep(2000); 
    } 

    static void SyncOp() 
    { 
     throw new Exception("Exception in sync method"); 
    } 

    async static void AsyncVoidOp() 
    { 
     await AsyncTaskOp(); 
    } 

    async static Task AsyncTaskOp() 
    { 
     await Task.Delay(300); 
     throw new Exception("Exception in async method"); 
    } 
} 

我缺少的東西?如何讓調試器在AsyncTaskOp()的異常處中斷/停止?

+0

你有沒有解決呢? –

+0

@RichardSzalay不,不幸的不是。我想我已經習慣了這一點。 –

回答

25

Debug菜單下,選擇Exceptions...。在例外對話框中,在Common Language Runtime Exceptions行旁邊檢查Thrown框。

+14

好的,我確實知道。但是然後調試器會打破所有*異常,而不僅僅是未處理的異常,對吧?所以這不完全是我要找的。 –

+3

@SebastianKrysmanski:雖然處理了異常。如果你有一個'async Task'方法,那麼這個異常就會被'async'狀態機捕獲並放在返回的'Task'上。 –

+10

在Visual Studio 2015中,異常設置位於'Debug' >>'Windows' >>'Exception Settings'(Ctrl + Alt + E) –

-2

我已將Task.Run(() =>中的匿名代理包裹在try/catch中。

Task.Run(() => 
{ 
    try 
    { 
      SyncOp()); 
    } 
    catch (Exception ex) 
    { 
      throw; // <--- Put your debugger break point here. 
        // You can also add the exception to a common collection of exceptions found inside the threads so you can weed through them for logging 
    } 

}); 
+2

之下,無法幫助,因爲調試器會在異常*被捕獲* - 不是它拋出*的地方。 –

3

我想聽聽有沒有人發現如何解決這個問題?也許在最新的視覺工作室......的設置?

一個討厭的,但可行的解決方案(在我的情況)是把我自己定製異常,然後修改斯蒂芬·克利裏的回答是:

在調試菜單上,選擇異常(你可以使用這個鍵盤快捷方式控制 + Alt + E)...在例外對話框中,在公共語言運行時例外行旁邊檢查投擲 框。

更具體,即添加定製異常到列表中,然後勾選其「時拋出」框。

E.g:

async static Task AsyncTaskOp() 
{ 
    await Task.Delay(300); 
    throw new MyCustomException("Exception in async method"); 
} 
+2

如果Task.Delay()拋出一個不同的異常會發生什麼? –

+0

托馬斯,我只是擴大了原始海報的例子。根據你的邏輯,*任何*可能會失敗 - 這是真的,但我們必須在上下文中回答......所以我們可以永遠繞圈......我的回答是讓調試器停在一個理想的環境中指向代碼,然後您可以查看本地變量值以及可能導致異常的原因。如果異常被拋出Task(按照OP),這很難實現,因爲它可能成爲調試的噩夢。 – Jimbob