我正在为“未处理的异常”事件编写处理程序,该事件会将异常转储到文件中,然后发送到服务器进行进一步分析.现在,它只是表明崩溃已经发生.我订阅了活动.在那种方法中,我调用了一个用于处理错误的函数.但是,当我在方法中编写以下代码时:
public async Task HandleException(Exception exception)
{
var dialog = new MessageDialog(exception.Message, "Exception occurred");
await dialog.ShowAsync();
}
并在调试模式下运行它,Visual Studio将显示Visual Studio即时调试器.首先,我认为这是我想在GUI线程快死了时显示消息框的问题.我将功能更改为:
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);
}
在调试器模式下,当我将断点放置在等待FileIO.WriteTextAsync(file,data)上时,它将在那里停止.按下继续按钮后,将显示与先前代码相同的窗口.从XAML事件调用它时,它运行正常.我已经在未处理的异常处理程序中搜索了google和*的异步方法,但是与我的问题没有任何关系.
我的问题是:该错误的原因是什么?是否可以在未处理的异常处理程序中使用异步方法?
更新:
到目前为止,谢谢您的回答.我在仔细调试代码后回答了第二个问题.事实证明,这是可能的,并且该功能正在按预期运行.
解决方法:
为了避免出现“ 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.但是,如您所见,这只会在调试模式下发生,在发行模型中,您的代码应该可以正常工作.