UWP: бросить / поднять не сбой приложения, исключение молча игнорируется - PullRequest
2 голосов
/ 26 февраля 2020

Я обнаружил, что мое приложение молча игнорирует исключения, и я не понимаю, почему.

Сначала я объясню, что работает: вы создаете пустое приложение 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, и я не уверен почему. Как я должен выявить исключение?

...