2014-07-06 90 views
2

當我在代碼中遇到異常時,它會一直拋出並一直回到app.g.i.cs文件。如果我將導致異常的方法封裝在try/catch中,它並不重要,它仍會回到App實例。WinRT中未處理的異常問題

這是我試圖使用方法:

public static async Task Clear() 
{ 
    userSessionToken = string.Empty; 

    var appdata = ApplicationData.Current; 
    StorageFile file = await appdata.LocalFolder.GetFileAsync("parseSession"); 

    try 
    { 
     await file.DeleteAsync(StorageDeleteOption.PermanentDelete); 
    } 
    catch (FileNotFoundException) 
    { 
     return; 
    } 
} 

每次我打了DeleteAsync方法,並且該文件不存在,我想到一個異常被拋出,併吞噬。相反,我的抓住從未受到打擊。它一直到app.g.i文件。

public void InitializeComponent() 
    { 
     if (_contentLoaded) 
      return; 

     _contentLoaded = true; 
#if DEBUG && !DISABLE_XAML_GENERATED_BINDING_DEBUG_OUTPUT 
     DebugSettings.BindingFailed += (sender, args) => 
     { 
      global::System.Diagnostics.Debug.WriteLine(args.Message); 
     }; 
#endif 
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION 
     UnhandledException += (sender, e) => 
     { 
// --> THIS Catches the exception <-- 
      if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break(); 
     }; 
#endif 
    } 

我應該注意到以下幾點:

try 
    { 
     await file.DeleteAsync(StorageDeleteOption.PermanentDelete); 
    } 
    catch (Exception) 
    { 
     return; 
    } 

有相同的結果,美中不足的是從來沒有擊中。

有人可以告訴我爲什麼我的異常處理程序(它不只是這一個,但在我的應用程序中的每一個)沒有被擊中?如果我的異常處理程序從來沒有被提供處理它們的機會,那麼正確處理異常真的很難。該應用程序被編寫爲通用Windows 8.1/Windows Phone 8.1應用程序。

我提供了完整的異常詳細信息,但是我的問題並不是真正導致異常的原因,而是爲什麼我的catch(即使我只是使用Exception而不是FileNotFoundException)沒有受到影響。

-  Exception {System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002) 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at Actions.Services.ParseRest.ParseSession.<Clear>d__e.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
    at Actions.Services.ParseRest.ParseRestUserService.<GetUserAsync>d__a.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at Actions.Repositories.User.UserRepository.<GetUserAsync>d__3.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at Actions.Apps.WinRT.App.<OnLaunchApplication>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
    at Microsoft.Practices.Prism.Mvvm.MvvmAppBase.<OnLaunched>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state) 
    at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()} System.Exception {System.IO.FileNotFoundException} 

謝謝!

+0

你的內在異常是什麼? –

+0

內部異常爲空 –

+0

我更新了我的OP與異常,雖然我的問題不是特別是什麼導致異常(我知道是什麼造成的);相反,爲什麼我的'try/catch'沒有抓住它。 –

回答

8

這個自動生成的代碼是相當不幸的,普遍的看法是而不是訂閱任何未處理的異常處理程序時附加一個調試器。既然這樣可以防止調試器向你顯示出現問題的那一刻出錯。在異步代碼中尤其痛苦,因爲拋出異常的代碼在調用堆棧中不可見。它似乎是必要的,沒有這個處理程序,它的工作非常糟糕。微軟有一些工作要做,以使這個更平滑。

您現在唯一真正的抵禦此權利的方法是使用Debug + Exceptions,勾選Thrown複選框以查看CLR異常。這會強制調試器在拋出異常時停止。

當您再次運行您的代碼時,您現在看到真正的問題,它是拋出的GetFileAsync()方法。由於它不在try {}塊中,因此您的catch子句不能吞下它。從技術上講,這是你可以推斷出來的,刪除不存在的文件不是錯誤。但是,當然,從調試器獲得幫助不會造成傷害。修復:

var appdata = ApplicationData.Current; 
try 
{ 
    StorageFile file = await appdata.LocalFolder.GetFileAsync("parseSession"); 
    await file.DeleteAsync(StorageDeleteOption.PermanentDelete); 
} 
catch (FileNotFoundException) 
{ 
    // Okay now. 
} 

這解決了您的問題。我還沒有準備好像你想要的那樣宣佈這是一個普遍的問題,你可能只是錯過了其他一些代碼失敗的情況,它不在try塊中。你被原諒了,你沒有從這些例外中獲得很好的調試信息。

+0

哇,我怎麼沒有意識到'GetFileAsync'方法拋出異常大聲笑。謝謝你,你幫了大忙! –