【问题标题】:Can you prevent exceptions on Xamarin.Mac from terminating the app?您可以防止 Xamarin.Mac 上的异常终止应用程序吗?
【发布时间】:2020-01-11 00:31:43
【问题描述】:

我知道在应用程序中捕获所有异常通常很糟糕,但在我的 WPF 应用程序中我会这样做:

  Application.Current.DispatcherUnhandledException += (s, e) => {
    ReportException(e.Exception, false);
    e.Handled = true;
  };

这对于防止次要功能(如拖放)和异步代码使应用程序崩溃非常有用 - 我记录并显示信息给用户。

我想在 Xamarin.Mac 中做同样的事情,但似乎没有等价物。我试过了:

  AppDomain.CurrentDomain.UnhandledException += (sender, args) => Log(args.Exception);
  TaskScheduler.UnobservedTaskException += (sender, args) =>
  {
      args.SetObserved();
      Log(args.Exception);
  };
  Runtime.MarshalManagedException += (sender, args) => Log(args.Exception);
  Runtime.MarshalObjectiveCException += (sender, args) => Log(args.Exception);

但是当在 async void 方法中崩溃时,TaskScheduler.UnobservedTaskExceptionMarshalManagedExceptionMarshalObjectiveCException 不会被调用, 而AppDomain.Current.UnhandledExceptione.IsTerminating 是get-only,所以我无法阻止应用退出。

对于 Android,有 AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironmentOnUnhandledException;

但是对于 Mac,似乎没有办法取消应用程序的宕机?

【问题讨论】:

  • 我听说您可以将 UIApplication.Main(args, null, "AppDelegate"); 包装在 try/catch 块中的 Main.cs 中,并且如果应用程序将退出 w/code 0 或 w/e 从崩溃而不是在此处退出进入您的 catch 块,它仍然可能会结束应用程序,但可能对调试有用。
  • AppDomain.Current.UnhandledException 非常适合用于记录目的,但它和包装 Main 都不能防止应用程序关闭
  • 有一个old thread,我想它也许可以回答你的问题。
  • 你知道这次关机发生在哪一行吗?它会引发异常捕获点吗?应用程序输出中捕获了什么异常?
  • @Saamer 异常发生在哪里并不重要——我想捕获所有异常并防止应用程序终止。我在AppDomain.Current.UnhandledException 处理程序中得到了异常,我在调试时看到它发生在 Xamarin 主循环中,它记录在应用程序输出中 没有办法阻止应用程序退出,就像在 WPF 上所做的那样跨度>

标签: xamarin xamarin.forms dispatcher unhandled-exception xamarin.mac


【解决方案1】:

与 Javascript 不同,原生 MacOS/iOS 开发不是异常安全的,并且不鼓励从异常中恢复,如 in Native iOS docs here 所述:

标准的 Cocoa 约定是异常表示程序员错误并且不打算从中恢复。默认情况下使代码异常安全将对通常实际上不关心异常安全的代码施加严重的运行时和代码大小惩罚。因此,ARC 生成的代码默认会在异常情况下泄漏,如果进程无论如何都将立即终止,这很好。关心从异常中恢复的程序应该启用该选项。

有一种方法可以通过在编译时添加命令来拒绝抛出异常,如上面的同一链接中所述。

不幸的是,由于 Xamarin 是本机开发,因此您会受到本机开发的限制。解决方案实际上是不允许在编程中引发异常,通过使用比较 if (x != null) 或类似 TryParse 的函数,并且仅在绝对需要时使用最高级别的 try-catch。

所以即使你尝试,如图here,你也无法防止崩溃,但你可以在应用程序肯定崩溃之前添加日志。 Here 的另一个很好的资源,它为本地开发人员解释了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多