Universal Apps中未处理的异常处理程序中的异步方法

时间:2016-07-19 11:04:51

标签: c# uwp win-universal-app

我正在为Unhandled Exception事件编写处理程序,我们将异常转储到文件然后发送到服务器进行进一步分析。现在它只会显示崩溃已经发生。我订阅了这个活动。在那个方法中,我调用了一个处理错误的函数。但是,当我在方法中写下这段代码时:

public async Task HandleException(Exception exception)
{
    var dialog = new MessageDialog(exception.Message, "Exception occurred");
    await dialog.ShowAsync();
}

在调试模式下运行它,Visual Studio显示Visual Studio即时调试器。首先,我认为当GUI线程正在死亡时,我试图显示Message Box的问题。我将功能更改为:

public async Task HandleManagedException(Exception 
{ 
    await FileStorage.WriteToFileAsync("someFile.txt", exception.ToString());
}

其中函数FileStorage.WriteToFileAsync如下所示:

public async Task WriteToFileAsync(string filename, string data)
{
    var file = await this.storageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
    await FileIO.WriteTextAsync(file, data);
}

在调试器模式下,当我在await FileIO.WriteTextAsync(file,data)上放置断点时,它就会停在那里。按下继续按钮后,同样的窗口显示在上一个代码中。从XAML事件调用它时它正常运行。我在google和StackOverflow中搜索了未处理的异常处理程序中的异步方法,但没有任何与我的问题相关的内容。

我的问题是:这个错误的原因是什么?是否可以在Unhandled异常处理程序中使用异步方法?

更新   到目前为止,谢谢你的答案。关闭调试代码后,我回答了自己的第二个问题。事实证明它是可能的,并且功能正在按预期工作。

1 个答案:

答案 0 :(得分:4)

要避免使用Visual Studio实时调试器对话框,我们可以将UnhandledExceptionEventArgs.Handled属性设置为true,如下所示:

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;
    this.UnhandledException += App_UnhandledException;
}

private async void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    e.Handled = true;
    await HandleException(e.Exception);
}

public async Task HandleException(Exception exception)
{
    var dialog = new MessageDialog(exception.Message, "Exception occurred");
    await dialog.ShowAsync();
}

在调试模式下,您会看到警告和即时调试器对话框,因为 App.g.i.cs 中有以下代码:

#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
    if (global::System.Diagnostics.Debugger.IsAttached) 
        global::System.Diagnostics.Debugger.Break();
};
#endif

我们在构建项目时会自动生成这些代码。从这些代码中,我们可以在调试模型中找到,如果有任何未处理的异常,它将调用Debugger.Break Method,这将导致警告和即时调试器对话框。

在我们的处理程序中设置e.Handled = true;可以避免这种情况。有关详情,请查看以下类似问题:How to try/catch all exceptions。但是,正如您所看到的,这只会发生在调试模式下,在发布模型中,您的代码应该运行良好。