Я обнаружил, что мое приложение молча игнорирует исключения, и я не понимаю, почему.
Сначала я объясню, что работает: вы создаете пустое приложение UWP, а затем ссылаетесь на внешнюю библиотеку. (в частности, эта библиотека реализована на F #) следующим образом:
namespace MyApp.Frontend.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
MyApp.Frontend.App.Throw(); // <- I insert this here
var app = new MyApp.Frontend.XF.App();
LoadApplication(app);
}
}
}
Реализация метода Throw
на стороне F # довольно проста:
namespace MyApp.Frontend.XF
open System
open Xamarin.Forms
type App() =
inherit Application(MainPage = MainPage())
static member Throw(): unit =
raise (new Exception ("foo"))
...
Это работает хорошо: приложение аварийно завершает работу, как и ожидалось.
Однако, если в приложении Xamarin.Forms я выбрасываю исключение из асинхронного рабочего процесса c, позже записываю его, чтобы отправить в основной поток (для убедитесь, что приложение вылетает), исключение игнорируется! (его тип исключения AggregateException
просто выводится на выход, ничего больше). Код для этой новой версии Throw
выглядит следующим образом:
namespace MyApp.Frontend.XF
open System.Threading.Tasks
open Xamarin.Forms
type App() =
inherit Application(MainPage = MainPage())
static member private CaptureException<'T> (task: Task<'T>) =
let nextTaskDelegate (prevTask: Task<_>) =
Device.BeginInvokeOnMainThread(fun _ ->
raise prevTask.Exception
)
raise prevTask.Exception
task.ContinueWith(nextTaskDelegate, TaskContinuationOptions.OnlyOnFaulted)
|> ignore
static member Throw(): unit =
async {
raise (System.Exception("blah"))
}
|> Async.StartAsTask
|> App.CaptureException
...
Этот метод сбивает приложение (переводит его в основной поток с помощью Device.BeginInvokeOnMainThread
, а также создает его в текущем потоке, на всякий случай) отлично работает на других платформах (например, Xamarin. Android), но как-то не так в UWP, и я не уверен почему. Как я должен выявить исключение?