我正在为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异常处理程序中使用异步方法?
更新 到目前为止,谢谢你的答案。关闭调试代码后,我回答了自己的第二个问题。事实证明它是可能的,并且功能正在按预期工作。
答案 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。但是,正如您所看到的,这只会发生在调试模式下,在发布模型中,您的代码应该运行良好。