Существуют ли возможные проблемы с производительностью, если я запускаю метод Async, который запускается каждую минуту и ​​вызывается из App.Xaml.cs OnStart ()? - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть этот код, и я предполагаю, что когда приложение открыто, оно будет запускать метод с именем PointChecker.CheckPoints(); каждую минуту.

Этот метод запускает обновление для моей базы данных синхронно с db2.Execute("UPDATE ..... etc");

Из того, что я понял, прочитав это:

https://xamarinhelp.com/xamarin-forms-async-task-startup/

Естьнесколько разных способов, которыми я мог бы реализовать это.

Я хотел бы знать, есть ли какие-либо проблемы с производительностью при запуске подобного кода, которые можно было бы уменьшить, если бы я попытался запустить его в другомпуть.В частности, были ли какие-либо недавние изменения в том, как работает Xamarin.Forms (мое приложение работает на iOS и Android через Forms), что я должен рассмотреть, и это может привести к лучшему способу выполнения этой задачи.

    public App() {
        InitializeComponent();
        DB.PopulateTables();
        MainPage = new Japanese.MainPage();
    }

    protected override async void OnStart() {
        await Task.Run(() => {
            StartTimer();
        });
    }

    public void StartTimer() {
       if (!stopWatch.IsRunning)
          stopWatch.Start();
          Device.StartTimer(new TimeSpan(0, 0, 1), () => {
             if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= 1) {
                PointChecker.CheckPoints();
                stopWatch.Restart();
             }
             return true;
          });
    }
    protected override void OnSleep() {
        stopWatch.Reset(); base.OnSleep();
    }
    protected override void OnResume() {
        base.OnResume(); stopWatch.Start();
    }

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

У меня тот же сценарий для синхронизации данных за заданный интервал времени, поэтому я использовал собственный сервис Android Sync Adapter .То, что он делает, вместо того, чтобы управлять вызовом в заданный интервал времени, он передает в вашу ОС Android.Я не имею ни малейшего представления о iOS, как вы можете достичь этого.

Если вы хотите реализовать адаптер синхронизации, используйте этот Пример кода

Я думаю, что это лучшийрешение для Android.

0 голосов
/ 12 октября 2018

Последние изменения в Xamarin не должны влиять на это.Этот метод является наиболее эффективным способом.Единственное, что я хотел бы рассмотреть, - это почему ваш метод должен быть асинхронным.Вы можете вызвать:

 protected override void OnStart()

В другой поток обсуждалось решение, которое не было блокировкой пользовательского интерфейса:

using Xamarin.Forms;
using System;
using System.Linq;
using System.Diagnostics;

namespace YourNamespace
{
    public partial class App : Application
    {
        private static Stopwatch stopWatch = new Stopwatch();
        private const int defaultTimespan = 1;

        protected override void OnStart()
        {
            // On start runs when your application launches from a closed state, 

            if (!StopWatch.IsRunning)
            {
                StopWatch.Start();
            }

            Device.StartTimer(new TimeSpan(0, 0, 1), () =>
            {
                // Logic for logging out if the device is inactive for a period of time.

                if (StopWatch.IsRunning && StopWatch.Elapsed.Minutes >= defaultTimespan)
                {
                    //prepare to perform your data pull here as we have hit the 1 minute mark   

                        // Perform your long running operations here.

                        InvokeOnMainThread(()=>{
                            // If you need to do anything with your UI, you need to wrap it in this.
                        });

                    stopwatch.Restart();
                }

                // Always return true as to keep our device timer running.
                return true;
            });
        }

        protected override void OnSleep()
        {
            // Ensure our stopwatch is reset so the elapsed time is 0.
            StopWatch.Reset();
        }

        protected override void OnResume()
        {
            // App enters the foreground so start our stopwatch again.
            StopWatch.Start();
        }
    }
}

Лучше всего, этот метод

Платформа агностика

0 голосов
/ 07 октября 2018

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

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

OnStart однако не является обработчиком событий.Просто обычный метод, который согласно документации ...

Разработчики приложения переопределяют этот метод для выполнения действий при запуске приложения.

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

StartTimer не является тяжелым методом, поэтому на самом деле не гарантирует его асинхронного вызова.Однако PointChecker.CheckPoints() синхронно вызывается для вашей базы данных.

Этот метод запускает обновление для моей базы данных синхронно с db2.Execute("UPDATE ..... etc");

Это может, однако, привести кблокировка, которая может влиять на производительность каждый раз, когда она вызывается.Это должен быть тот, который включен в асинхронный вызов или рефакторинг, чтобы быть нативным асинхронным методом.

//...

protected override void OnStart() {
    PointsChecking += OnPointsChecking; //subscribe to event
    StartTimer(); //start the timer as normal.
}

private event EventArgs PointsChecking = delegate { };

private async void OnPointsChecking(object sender, EventArgs args) {
    //asynchronously check points without blocking main thread
    await Task.Run(() => {
        PointChecker.CheckPoints();
        stopWatch.Restart();
    });
}

public void StartTimer() {
    if (!stopWatch.IsRunning)
        stopWatch.Start();
    Device.StartTimer(new TimeSpan(0, 0, 1), () => {
        if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= 1) {
            PointsChecking(null, EventArgs.Empty); //invoked event
        }
        return true;
    });
}

//...

Таймер будет отвечать за выдачу события для обработки повторной операции.Делая обработчик событий асинхронным, вы избегаете блокировки основного потока и получаете дополнительное преимущество, заключающееся в возможности перехвата и обработки любых исключений, вызванных вызванной операцией базы данных, если это необходимо.

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