Пытаясь внедрить некоторые свойства автосохранения в мое приложение 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 сам по себе и в основном столько времени, сколько мне нужно.
Любое объяснение, чтобы помочь мне Я буду очень признателен за понимание того, что здесь происходит, так как я бы хотел реализовать код, понимая, почему он работает, а не просто как он работает.
Спасибо!