Xamarin iOS видит непредвиденное поведение с BackgroundTask - PullRequest
0 голосов
/ 15 февраля 2020

Пытаясь внедрить некоторые свойства автосохранения в мое приложение Xamarin Cross Platform, я столкнулся с тем, что кажется неправильным, и пытаюсь понять, что происходит. Это на Xamarin.Forms v4.4 и тестирование с таргетингом на iOS 13 (как на симуляторе, так и на реальном устройстве).

В моем методе App.xaml.cs OnSleep я хотел добавить несколько логи c для автоматического сохранения пользовательских данных с помощью вызова API. Для аргумента скажем, что в худшем случае ios это сохранение API может занять целую минуту. Из моего прочтения, кажется, довольно последовательно утверждается, что OnSleep не гарантированно будет работать и не должен использоваться для чего-либо, что будет длиться более 5-10 секунд. Это побудило меня провести некоторое исследование фоновых задач и реализовать простой контрольный пример, основанный на некоторых сообщениях в блогах и других ответах, которые я видел на форумах.

Моя цель, заключающаяся в этом, заключается в том, чтобы иметь возможность Автосохранение из фона, при этом мое приложение не закрывается ОС.

App.xaml.cs:

    protected override async void OnSleep()
        {
            MessagingCenter.Send(new RunBackgroundSaveMessage(), "RunBackgroundSaveMessage");
        }

А затем я подписываюсь и обрабатываю сообщение в моем iOS Speci c Project AppDelegate.cs:

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

            MessagingCenter.Subscribe<RunBackgroundSaveMessage>(this, "RunBackgroundSaveMessage", InitiateBackgroundAutoSave);

            return base.FinishedLaunching(app, options);
        }

        private nint curTaskID = UIApplication.BackgroundTaskInvalid;
        private async void InitiateBackgroundAutoSave(RunBackgroundSaveMessage message)
        {
            Console.WriteLine("InitiateBackgrounding");
            DateTime StartDT = DateTime.Now;

            curTaskID = UIApplication.SharedApplication.BeginBackgroundTask(() =>
            {
                Console.WriteLine("BackgroundTimeExpiredCallback");
                Console.WriteLine(DateTime.Now.Subtract(StartDT).TotalSeconds);
                //End Task
                UIApplication.SharedApplication.EndBackgroundTask(curTaskID);
                curTaskID = UIApplication.BackgroundTaskInvalid;
            });
            Console.WriteLine("curTaskID: " + curTaskID);

            //DoWork
            while (DateTime.Now.Subtract(StartDT).TotalMinutes < 15)
            {
                Console.WriteLine("FROM IOS: " + DateTime.Now.Subtract(StartDT).TotalMinutes);
                Console.WriteLine("FROM IOS: " + "Running API");
                await Helpers.WebAPI.GetAPIInfoAsync();
                await Task.Delay(1000 * 15);
            }

            Console.WriteLine("EndBackgrounding");
            UIApplication.SharedApplication.EndBackgroundTask(curTaskID);
            curTaskID = UIApplication.BackgroundTaskInvalid;
        }

Вот где мы получаем то, что я не понимаю. Хотя ни одна из прочитанных мной публикаций не указывает на проблему с продолжительностью времени до истечения срока действия BackgroundTask, и вся документация указывает на тот факт, что задача должна иметь около 600 секунд времени выполнения в фоновом режиме, моя функция обратного вызова backgroundTimeExpired имеет вид всегда вызывается примерно через 26 секунд, с оставшимися 4 секундами, что означает, что у задачи действительно есть только 30 секунд, а не 600.

Теперь, пока l oop у меня есть это не окончательная реализация работы, которую я хотел бы выполнить, а заполнитель для замены чего-то, что требует много времени для запуска, в этом случае он вызывает простую конечную точку GET API каждые 15 секунд в течение 15 минут. Что я не понимаю, так это то, что l oop работает отлично, с или без начала фоновой задачи. Все, что я прочитал, указывает на то, что мой код перестанет работать, как только приложение окажется в фоновом режиме, если я не установил его между BeginBackgroundTask и EndBackgroundTask.

Однако все, что я тестировал, показывает, что даже после задание было завершено, l oop работает в течение полных 15 минут (в отличие от приостановки или прекращения работы приложения), кроме того, если я вообще не заморачиваюсь с BeginBackgroundTask, кажется, что он работает нормально, так как хорошо. Я даже вынул сообщение и просто вставил while l oop в метод OnSleep, и даже там, несмотря на то, что, как я ожидал, он работал в течение полных 15 минут с операционной системой, завершающей мое приложение.

И Я понятия не имею, что об этом думать, так как я нахожусь с работающей функциональностью, но не по причинам, которые я думал. Вместо того, чтобы работать, потому что я успешно поддерживаю BackgroundTask, он работает, потому что ОС, похоже, не заботится о приостановке моего приложения, как я думал. Даже несмотря на то, что все, что я прочитал, кажется, кричит о том, что я этого не делаю, даже кажется, что я мог бы просто использовать метод OnSleep сам по себе и в основном столько времени, сколько мне нужно.

Любое объяснение, чтобы помочь мне Я буду очень признателен за понимание того, что здесь происходит, так как я бы хотел реализовать код, понимая, почему он работает, а не просто как он работает.

Спасибо!

...