WinRT中的未处理exception问题

当我在代码中遇到一个exception时,它会一直抛出并一直回到app.gics文件。 如果在try / catch中引发exception的方法并不重要,它仍会回到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方法,并且该文件不存在,我希望抛出和吞下exception。 相反,我的抓住从未受到打击。 它一直泡到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; } 

有同样的结果,捕获是从来没有打。

有人可以告诉我为什么我的exception处理程序(这不是只是这个,但在我的应用程序中的每一个)都没有被击中? 如果我的exception处理程序从来没有被提供处理它们的机会,那么正确处理exception真的很难。 该应用程序被写为通用Windows 8.1 / Windows Phone 8.1应用程序。

我提供了完整的exception详细信息,但是我的问题并不是真的是什么导致了exception,而是为什么我的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} 

谢谢!

这个自动生成的代码是相当不幸的,通常的想法是在附加debugging器时订阅任何未处理的exception处理程序。 既然这样可以防止debugging器向你显示出错的那一刻出了什么问题。 在asynchronous代码中尤其痛苦,因为抛出exception的代码在调用堆栈上不可见。 它似乎是必要的,没有这个处理程序,它的工作非常糟糕。 微软有一些工作要做,以使这个更顺畅。

您现在唯一真正的防御就是使用Debug + Exceptions,勾选Throwncheckbox以查看CLRexception。 这会强制debugging器在引发exception时停止。

当您再次运行您的代码时,您现在看到了真正的问题,它是抛出的GetFileAsync()方法。 由于它不在try {}块中,所以catch子句不能吞下它。 从技术上讲,这是你可以推断,删除不存在的文件不是一个错误。 但是,当然,从debugging器获得帮助不会造成伤害。 固定:

 var appdata = ApplicationData.Current; try { StorageFile file = await appdata.LocalFolder.GetFileAsync("parseSession"); await file.DeleteAsync(StorageDeleteOption.PermanentDelete); } catch (FileNotFoundException) { // Okay now. } 

这解决了你的问题。 我还没有准备好宣布这是一个普遍的问题,你可能只是错过了一些其他的代码失败的情况下,不在try块中。 你被原谅了,你没有从这些例外中得到很好的debugging信息。