簡體   English   中英

WinRT中未處理的異常問題

[英]Unhandled Exception issue in WinRT

當我在代碼中遇到異常時,它會一直拋出並冒泡回app.gics文件。 如果我在try / catch中包裝導致異常的方法並不重要,它仍然會回到App實例。

這是我嘗試使用的方法:

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.gi文件。

    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}

謝謝!

這個自動生成的代碼非常不幸,常見的做法是在附加調試器時訂閱任何未處理的異常處理程序。 因為這樣可以防止調試器在出現問題時向您顯示出現了什么問題。 特別是在異步代碼中很痛苦,因為拋出異常的代碼在調用堆棧中是不可見的。 然而,它似乎是必要的,沒有那個處理程序,它的工作效果非常差。 微軟有一些工作要做,以使這更順利。

你現在唯一真正的防御就是使用Debug + Exceptions,勾選CLR異常的Thrown復選框。 這會強制調試器在拋出異常時停止。

當您再次運行代碼時,您現在看到了真正的問題,它是拋出的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 {}塊中。 你原諒了,你沒有從這些異常中獲得良好的調試信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM