Есть ли способ избежать необходимости защищенного переопределения asyn c void OnStart () - PullRequest
1 голос
/ 22 февраля 2020

Я понимаю, что OnStart () - это просто событие, поэтому я понимаю, что нет проблемы с возвращением void. Однако я все еще получаю раздражающее сообщение с предупреждением

Есть ли альтернатива, позволяющая мне запускать асинхронные c методы в OnStart ()?

Могу ли я сделать что-то вроде создания задачи и они (или весь мой код, который в настоящее время находится в OnStart) выполняются внутри этой задачи? или я мог бы использовать конструкцию _ =, чтобы игнорировать вывод Задачи, выполняющейся внутри OnStart?

Обновление:

Основываясь на предложении Никоси, вот что я думаю сделать :

Приложение

public partial class App : Application
{
    public async Task CheckLatestVersion()
    {
        try
        {
            var isLatest = await CrossLatestVersion.Current.IsUsingLatestVersion();

            if (!isLatest)
            {
                var update = await MainPage.DisplayAlert("New Version", $"\nThere is a new version of this app available.\n\nWould you like to update now?\n", "Yes", "No");

                if (update)
                {
                    await CrossLatestVersion.Current.OpenAppInStore();
                }
            }
        }

        catch (Exception ex)
        {
            var ignore = ex;
        }
    }

    private event EventHandler started = delegate { };

    protected override void OnStart() {
       this.started += onStarted;      //Subscribe to event
       started(this, EventArgs.Empty); //Raise event
    }

    protected async void onStarted(object sender, EventArgs args)
    {
        try
        {
            if (Connectivity.NetworkAccess == NetworkAccess.Internet)
            {
                if (Settings.Rev == REV.No && (new[] { 15, 30, 50 }).Contains(Settings.Trk2))
                {
                    await ReviewAppAsync(Settings.Trk2);
                }
                if (App.devIsPhysical && (new[] { 10, 20, 30 }).Contains(Settings.Trk2))
                {
                    await CheckLatestVersion();
                }
                // This
                await Helper.PopulateMetrics();
                // Or this
                _ = Helper.PopulateMetrics();
                await Helper.LogStart();
            }
        }
        catch(Exception)
        {
            ;
        }
        this.started -= onStarted; //Unsubscribe (OPTIONAL but advised)
    }
}

Помощник

    public static async Task PopulateMetrics()
    {
        await Task.Run(() =>
        {
            if (App.CPUSpeed == 0)
            {
                var stopWatch = Stopwatch.StartNew();
                stopWatch.Start();
                ArrayList al = new ArrayList(); for (int i = 0; i < 5000000; i++) al.Add("hello");
                App.CPUSpeed = 20000 / stopWatch.ElapsedMilliseconds;
            }
        });

    }

    public async Task ReviewAppAsync(int count)
    {
        try
        {
            async Task<bool> DelayAndDisplayAlert()
            {
                await Task.Delay(60000);
                return await MainPage.DisplayAlert("Review", $"\nWe noticed that you've used this application {count} times. We'd love to get some feedback for the application.\n\nCan you help us by rating the application or leaving a review?\n", "Yes", "No");
            }

            if (count == 0 || await DelayAndDisplayAlert())
            {
                if (Plugin.StoreReview.CrossStoreReview.IsSupported)
                {
                    if (Xamarin.Forms.Device.RuntimePlatform == "iOS")
                        Plugin.StoreReview.CrossStoreReview.Current.OpenStoreReviewPage("1477984412");
                    else if (Xamarin.Forms.Device.RuntimePlatform == "Android")
                        Plugin.StoreReview.CrossStoreReview.Current.OpenStoreReviewPage("com.ankiplus.Japanese");
                }
            }
        }
        catch (Exception ex)
        {
            Helper.RegisterCrash(ex,
                new Dictionary<string, string> {
                    {"ReviewAppAsync", "Exception" },
                    {"Device Model", DeviceInfo.Model },
                    {"Exception", ex.ToString()}
                });
        }
    }

1 Ответ

2 голосов
/ 22 февраля 2020

OnStart на самом деле не является обработчиком событий. Это неправильное представление о том, как была построена структура. Тем не менее, вы можете создать событие и асинхронный обработчик c, чтобы ваш асин c код ожидался, как и ожидалось.

private event EventHandler started = delegate { };

protected override void OnStart() {
    this.started += onStarted;      //Subscribe to event
    started(this, EventArgs.Empty); //Raise event
}

protected async void onStarted(object sender, EventArgs args) {
    try {

        //await custom code here

    } catch {
        //handle errors
    }
    //this.started -= onStarted; //Unsubscribe (OPTIONAL but advised)
}

Асинхронный обработчик событий - это единственное исключение, где async void разрешено и может быть правильно обработанным.

Использование async void с переопределенным обработчиком не событий OnStart приведет к тому, что любые исключения, с которыми встречаются, поскольку async void в не обработчике событий срабатывают и забывают .

Справочник Асинхронное / ожидание - Лучшие практики в асинхронном программировании

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...