【问题标题】:Unhandled Exception issue in WinRTWinRT 中未处理的异常问题
【发布时间】:2014-08-27 03:45:27
【问题描述】:

当我在代码中遇到异常时,它总是会抛出并冒泡回到 app.g.i.cs 文件。如果我将导致异常的方法包装在 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.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;
    }

结果相同,catch 永远不会被击中。

谁能告诉我为什么我的异常处理程序(不仅仅是这个,而是我的应用程序中的每个)都没有被击中?如果我的异常处理程序从未有机会处理它们,那么正确处理异常真的很困难。该应用程序被编写为通用 Windows 8.1/Windows Phone 8.1 应用程序。

我提供了完整的异常详细信息,但我的问题并不是导致异常的真正原因,而是为什么我的捕获(即使我只是使用 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}

谢谢!

【问题讨论】:

  • 你内心的异常是什么?
  • 内部异常为空
  • 我用异常更新了我的 OP,虽然我的问题不是具体是什么导致了异常(我知道是什么导致的);而是为什么我的try/catch 没有抓住它。

标签: c# excel exception-handling windows-runtime


【解决方案1】:

这个自动生成的代码是相当不幸的,常识是在附加调试器时订阅任何未处理的异常处理程序。因为这会阻止调试器在出错时向您显示出错的地方。在异步代码中尤其痛苦,因为引发异常的代码在调用堆栈上不可见。然而,这似乎是必要的,如果没有那个处理程序,它的工作效果会很差。 Microsoft 需要做一些工作来使这更顺畅。

您现在唯一真正的防御方法是使用 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 {} 块中的代码失败案例。原谅您,您没有从这些异常中获得良好的调试信息。

【讨论】:

  • 哇,我怎么没有意识到GetFileAsync 方法正在抛出异常,哈哈。谢谢你,你帮了很多忙!
猜你喜欢
  • 2010-09-29
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多