2014-12-22 4 views
1

Если пользователь нажимает кнопку «домой» или открывает переключатель приложений или получает входящий вызов, текущая задача (веб-запрос) должна заканчиваться в фоновом режиме. Я не использую NSURLSession для этого, потому что теперь я не хочу менять текущий класс. Поэтому я хочу использовать background-safe tasks.Правильная реализация при использовании фоновой безопасности вместе с async/await

Я попытался это:

public async Task retrieveCarList(){ 
    backgroundTaskID = UIApplication.SharedApplication.BeginBackgroundTask (() => { 
     if(backgroundTaskID != 0){ 
      UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskID); 
      backgroundTaskID = 0; 
     } 
    }); 

    List<Car> carList = await manager.GetCarList(); 
    if(carList != null) { 
     this.list = carList; 
    } else { 
     new UIAlertView("Error occurred", "", null, "OK", null).Show(); 
    } 

    if(backgroundTaskID != 0){ 
     UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskID); 
     backgroundTaskID = 0; 
    } 
} 

Это похоже на работу, но я должен проверить его больше.

Вопросы:

  1. Могу ли я использовать BeginBackgroundTask/EndBackgroundTask везде в моем приложении? Большинство examples использовать это только в DidEnterBackground ...

  2. Как система знает, где начинается и заканчивается эта фоновая нить?

  3. Используется ли код между BeginBackgroundTask и EndBackgroundTask выполненными даже с использованием пользовательского интерфейса?

  4. Это правильная реализация после сообщения в блоге Multitasking in iOS: the MonoTouch way – Part I: Pressing the Home button, но с async/await?

Edit 1:

Теперь я пытался работать с Console.WriteLine. Кажется, что выполняется выражение await, но после этого код будет выполнен, только если пользователь снова откроет приложение. Я беспокоюсь о том, что EndBackgroundTask выполняется только в том случае, если пользователь вернулся в приложение. Поэтому приложение может быть убито, если EndBackgroundTask не вызывается.

С другой стороны, если я не использую безопасную для фона задачу, приложение не будет делать веб-запрос в фоновом режиме больше, если нажата кнопка дома. Так что это вроде работает ...

Как я могу поместить все строки кода в выражение await? Тогда весь код должен быть выполнен или?

Edit 2:

Ввод выражения await в между System.Action вызывает приложение к сбою и не показаны ошибки. Я также пытался использовать BeginBackgroundTask в retrieveCarList() и использовать EndBackgroundTask в ожидаемом GetCarList(), но код выполняется только в том случае, если я вернулся в приложение. Кроме того, я попытался обернуть мой await в другом Task.Run, но это создает проблемы, потому что я имею доступ к связанным с UI материалу, который невозможен с этой структурой. Моя первая попытка по-прежнему кажется лучшей, но у нее есть недостаток, о котором говорилось выше. Если кто-то лучше реализует, отправьте его.

ответ

3

Решения:

1.)Xamarin docs сказать, что я могу использовать этот шаблон везде. Это также указано в Apple docs.

Этот метод можно вызвать в любой момент выполнения вашего приложения.

2.)Dimitris Tavlikos states

Это после вызова BeginBackgroundTask, где начинается ваш фон время.

3.) Пользовательский интерфейс поток, кажется, быть приостановлено в соответствии с Developing C# Apps for iPhone and iPad using MonoTouch: iOS Apps Development by Bryan Costanich.

4.) Мой подход, кажется, работает нормально. Теперь я помещаю свой Console.WriteLine до EndBackgroundTask, и он называется как он должен! Выполняется все между BeginBackgroundTask и EndBackgroundTask. Только backgroundTaskID не очищается, но другие реализации также этого не делают.