您可以防止 Xamarin.Mac 上的异常终止应用程序吗?
Can you prevent exceptions on Xamarin.Mac from terminating the app?
我知道在应用程序中捕获所有异常通常是不好的,但在我的 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.UnobservedTaskException
、MarshalManagedException
和MarshalObjectiveCException
没有被调用,
AppDomain.Current.UnhandledException
的 e.IsTerminating
是只获取的,所以我无法阻止应用程序退出。
对于 Android 有 AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironmentOnUnhandledException;
但是对于 Mac 似乎没有办法取消正在关闭的应用程序?
与 Javascript 不同,本机 MacOS/iOS 开发不是异常安全的,并且不鼓励从异常中恢复,如所述 in Native iOS docs here:
The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.
有一种方法可以通过在编译时添加命令来拒绝抛出异常,正如上面相同的 link 中所述。
不幸的是,由于 Xamarin 是 Native 开发,因此您会受到 Native 开发的限制。解决方案实际上是不允许在编程中引发异常,通过使用比较 if (x != null)
或类似 TryParse
的函数,并且仅在绝对需要时才在最高级别使用 try-catch。
所以即使您尝试了,如图所示 here, you will not be able to prevent a crash, but you can add logs before the app will certainly crash. Here 的另一个很好的资源,它为本地开发人员解释了它。
我知道在应用程序中捕获所有异常通常是不好的,但在我的 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.UnobservedTaskException
、MarshalManagedException
和MarshalObjectiveCException
没有被调用,
AppDomain.Current.UnhandledException
的 e.IsTerminating
是只获取的,所以我无法阻止应用程序退出。
对于 Android 有 AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironmentOnUnhandledException;
但是对于 Mac 似乎没有办法取消正在关闭的应用程序?
与 Javascript 不同,本机 MacOS/iOS 开发不是异常安全的,并且不鼓励从异常中恢复,如所述 in Native iOS docs here:
The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from. Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.
有一种方法可以通过在编译时添加命令来拒绝抛出异常,正如上面相同的 link 中所述。
不幸的是,由于 Xamarin 是 Native 开发,因此您会受到 Native 开发的限制。解决方案实际上是不允许在编程中引发异常,通过使用比较 if (x != null)
或类似 TryParse
的函数,并且仅在绝对需要时才在最高级别使用 try-catch。
所以即使您尝试了,如图所示 here, you will not be able to prevent a crash, but you can add logs before the app will certainly crash. Here 的另一个很好的资源,它为本地开发人员解释了它。