我有一个在 iOS 上运行的 Xamarin Forms 应用程序,它使用 iOS LocationManager 来获取用户位置。
有时这不起作用,但代码没有命中我的 try / catch 异常块,而是抛出 SIGABRT System.InvalidOperationException。
我认为我遇到了以下关于 iOS 异常封送处理的文章中列出的问题,但我不完全理解该文章,并且除了使用构建时标志之外没有在文章中看到解决方案,但即使如此,这也是令人困惑的我不知道我应该使用哪些标志。
我想我需要将 iOS Objective-C 异常转换为带有标志的 C# 异常,但不确定使用哪个标志。
https://learn.microsoft.com/en-us/xamarin/ios/platform/exception-marshaling
这是我在 iOS 中使用的代码块,想知道如何捕获异常并在出现错误时返回“null”而不是使应用程序崩溃。
try
{
using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), useSynchronizationContext: false))
{
// request the current location
locationManager.RequestLocation();
// return the task to the caller
return await taskCompletionSource.Task.ConfigureAwait(continueOnCapturedContext: false);
}
}
catch (Exception)
{
// LOG THE EXCEPTION
// return null so we don't blow up the calling code for now.
return null;
}
finally
{
// remove the attached handler
locationManager.LocationsUpdated -= handler;
locationManager.Dispose();
}
这是它发送给我的堆栈跟踪。
TaskCompletionSource`1[TResult].SetCanceled () LocationService+<>c__DisplayClass9_0.b__1 () <.cctor>b__26_0(系统.对象对象) CancellationCallbackInfo.ExecutionContextCallback(System.Object obj) ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext、System.Threading.ContextCallback 回调、 System.Object 状态、System.BooleanserveSyncCtx) ExecutionContext.Run(System.Threading.ExecutionContext executionContext、System.Threading.ContextCallback 回调、 System.Object 状态、System.BooleanserveSyncCtx) ExecutionContext.Run(System.Threading.ExecutionContext executionContext、System.Threading.ContextCallback 回调、 System.Object状态)CancellationCallbackInfo.ExecuteCallback() CancellationTokenSource.CancellationCallbackCoreWork (System.Threading.CancellationCallbackCoreWorkArguments 参数) CancellationTokenSource.ExecuteCallbackHandlers (System.Boolean 抛出第一个异常)
CancellationTokenSource.ExecuteCallbackHandlers (System.Boolean throwOnFirstException) CancellationTokenSource.NotifyCancellation (System.Boolean throwOnFirstException) CancellationTokenSource.TimerCallbackLogic (System.Object obj) 定时器+调度程序.TimerCB (System.Object o) IThreadPoolWorkItem.ExecuteWorkItem() ThreadPoolWorkQueue.Dispatch()
在我的 iOS AppDelegate.cs 中,我有 AppDomain.CurrentDomain.UnhandledException 事件处理程序,但在上面的代码中它也没有被命中。
最好记录异常而不是使应用程序崩溃。
AppDomain.CurrentDomain.UnhandledException
未被调用的问题显然是一个bug。
错误项中提到了一个解决方法,可以调用事件:
ObjCRuntime.Runtime.MarshalManagedException += (_, exceptionArgs) =>
{
exceptionArgs.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.UnwindNativeCode;
};
YMMV.