使用 UnobservedTaskException 停止 HockeyApp 使我的 Xamarin iOS 应用程序崩溃

Stopping HockeyApp crashing my Xamarin iOS app with UnobservedTaskException

我们有一个位于高度异步 PCL 库之上的 Xamarin iOS 应用程序。有可能偶尔某个任务会在库中出现故障而未被观察到。因此,我们在 TaskScheduler 上连接了 UnobservedTaskException 处理程序,以确保这不一定会导致我们的应用程序宕机。

在我们启用 HockeyApp 以集中崩溃报告之前,它工作正常。 Hockey 为未观察到的任务异常添加了自己的处理程序,它总是在向其服务器发送崩溃报告后终止应用程序。我对他们为 AppDomain UnhandledException 处理程序执行此操作没有问题,但我需要阻止他们在未观察到的任务异常时杀死应用程序。

似乎有一种机制可以为这些异常安装自定义处理程序,但我看不到如何在 Xamarin iOS Hockey SDK

中安装它

这是我们用来启用 Hockey 的代码

var manager = BITHockeyManager.SharedHockeyManager;

manager.Configure(APPID);
#if DEBUG
   manager.DebugLogEnabled = true;
#endif

manager.StartManager();

有谁知道如何针对 UnobservedTaskExceptions 覆盖 HockeyApp 的默认行为?

根据这个支持问题,答案是否定的。

https://support.hockeyapp.net/discussions/problems/60521-hockeysdkuwp-413-no-way-to-disable-unobservedtaskexceptions

并且此提交似乎正在尝试解决问题

https://github.com/bitstadium/HockeySDK-Windows/commit/1c1bc9715e64dd1283b3dc5db40ccdc9e59f4fc3

UnobservedTaskException EventHandler 被硬编码在 StartManager 方法中,无法直接删除。

TaskScheduler.UnobservedTaskException += (sender, e) => ThrowExceptionAsNative(e.Exception);

参考:https://github.com/bitstadium/HockeySDK-Xamarin/blob/28e67ecba14d00c8bea8043e08678af6044d33cf/source/HockeySDK.iOSBindings/Additions.cs#L43

就个人而言,我从源代码构建,public仅公开 ThrowExceptionAsNative 并将配置方法添加到 include/exclude 调用 StartManager 时的默认处理程序。这就像 HockeyApp 对 HockeySDK-Windows api.

所做的一样

因此,当捕获到 UnobservedTaskException 时,您可以选择自行处理或将其作为本机异常抛出。

这很像原始的 Xamarin 本机绑定,我不明白他们为什么这样做,因为在 HockeySDK-Windows 代码中,他们删除了默认处理共 UnobservedTaskException 个:

Since .NET 4.5, by default, UnobservedTaskExceptions do no longer cause the app to crash. The SDK has not been adapted for this and still logs these errors and causes the program to exit, though this might not be needed or intended.

Users who wish to continue using the handler, should add calls to RegisterUnobservedTaskExceptionHandler() or RegisterDefaultUnobservedTaskExceptionHandler() after calling Configure().

对于几个不想自定义构建 HockeySDK.Xamarin 的客户,我通过反射 [=12] 之后删除了 EventHandler =] 调用并添加我们的自定义处理程序。使用这种方法,如果需要,您将没有 public ThrowExceptionAsNative 可用于将异常作为本机异常抛出,但是更多的反射可以做到:-/

我用这行代码解决了这个问题:

var ex = t.Exception;

当任务抛出异常时 我把结果

if ((t.IsFaulted) || (t.IsCanceled))
{
    var ex = t.Exception;