В предыдущем выпуске этой серии о том, как разработать приложение для Windows Phone с нуля, мы говорили о программном создании вторичной плитки внутри нашего приложения и отображении различного содержимого на передней и задней сторонах вторичной плитки.
На этот раз мы представим концепцию фоновых агентов для Windows Phone. Фоновый агент — это фрагмент кода приложения, который может выполняться, даже если приложение не запущено. Фоновые агенты могут использоваться для периодического выполнения некоторых действий. В зависимости от типа действия и типа планирования фоновые агенты могут иметь тип PeriodicTask (который выполняется регулярно в течение короткого промежутка времени) или тип ResourceIntensiveTask (который выполняется в течение более длительного периода времени, но не через регулярный интервал). , Каждое приложение может иметь не более одной PeriodicTask и одной ResourceIntensiveTask. Есть ограниченияпри использовании как PeriodicTask, так и ResourceIntensiveTask. Одной из наиболее важных вещей, которые следует иметь в виду, является то, что PeriodicTask будет запускаться примерно каждые 30 минут в течение не более пары секунд, и он будет продолжаться примерно два раза в час в течение 14 дней подряд (при условии, что PeriodicTask не завершится сбоем). ). Если приложение не обновляло PeriodicTask в течение этих 14 дней, PeriodicTask будет удален из графика. Думая об этом, это имеет смысл. Если пользователь не использует ваше приложение в течение столь длительного времени, вероятно, нет необходимости продолжать выполнять код для этого приложения в фоновом режиме.
Для EvenTiles мы будем использовать PeriodicTask, чтобы регулярно обновлять нашу Вторичную плитку. Поскольку обновление Secondary Tile является относительно простым действием, это идеальный кандидат для PeriodicTask. Таким образом, мы можем воплотить в жизнь нашу Вторичную плитку (в конце концов, все изменится на ней на начальном экране телефона пользователя), независимо от состояния выполнения нашего приложения. Этот метод может, например, использоваться для обновления информации о погоде или количества новых доступных электронных писем, чтобы просто держать пользователя в курсе. В нашем примере приложения мы будем использовать PeriodicTask для простого отображения разных строк на обратной стороне вторичной плитки. Причина, по которой вы выбрали что-то настолько простое, заключается в том, чтобы сконцентрироваться на простой функциональности PeriodicTask,его отношение к приложению и способы обмена данными между приложением и его периодической задачей.
Чтобы использовать PeriodicTask, нам нужно добавить новый проект в наше решение. Visual Studio уже содержит шаблон для агента запланированных задач Windows Phone, как показано на следующем рисунке:
Во вновь созданном PeriodicTask вы найдете метод OnInvoke . Это метод, в который вы добавите функциональность, которую вы хотели бы выполнить в фоновом режиме. Важно вызвать метод NotifyComplete как последний оператор внутри вашего метода OnInvoke . Каждый раз, когда ваш код выполняется, он будет выполняться в отдельном потоке. Поскольку PeriodicTask выполняется независимо от приложения (после того, как приложение запустило PeriodicTask), оно не может обновить пользовательский интерфейс приложения, которому оно принадлежит.
Чтобы иметь возможность запускать PeriodicTask из своего приложения, первое, что вы должны сделать, это добавить ссылку на PeriodicTask в проект вашего приложения:
Добавив ссылку на PeriodicTask, вы фактически установили связь между ней и приложением. Это видно внутри файла WPAppManifest.xml:
Периодическая задача в манифесте:
<Tasks> <DefaultTask Name="_default" NavigationPage="MainPage.xaml" /> <ExtendedTask Name="BackgroundTask"> <BackgroundServiceAgent Specifier="ScheduledTaskAgent" Name="EvenTilesScheduledTaskAgent" Source="EvenTilesScheduledTaskAgent" Type="EvenTilesScheduledTaskAgent.ScheduledAgent" /> </ExtendedTask> </Tasks>
Следующее, что нужно сделать, это запустить PeriodicTask из приложения. Конечно, хорошей практикой является держать пользователя под контролем, поэтому мы собираемся создать PeriodicTask в результате действий пользователя. В эпизоде 9 EvenTiles мы добавили кнопку в MainPage для создания вторичной плитки. Поскольку мы хотим, чтобы этот Вторичный Плитка регулярно менял текст на задней стороне (даже без активного приложения), имеет смысл создать PeriodicTask как часть того же обработчика события Click. Код для создания и удаления PeriodicTask выглядит следующим образом:
Создать и удалить PeriodicTask:
private void StartPeriodicAgent() { RemovePeriodicAgent(); evenTilesPeriodicTask = new PeriodicTask(evenTilesPeriodicTaskName); evenTilesPeriodicTask.Description = "EvenTilesPeriodicTask"; try { ScheduledActionService.Add(evenTilesPeriodicTask); } catch (InvalidOperationException ex) { if (ex.Message.Contains("BNS Error: The action is disabled")) { MessageBox.Show("Background agents for this application are disabled."); } } } private void RemovePeriodicAgent() { var runningPeriodicTask = ScheduledActionService.Find(evenTilesPeriodicTaskName) as PeriodicTask; if (runningPeriodicTask != null) { ScheduledActionService.Remove(evenTilesPeriodicTaskName); } }
Обратите внимание, как мы используем ExceptionHandling для перехвата InvalidOperationException. Это исключение обычно генерируется, если пользователь отключил фоновую обработку для нашего приложения, что он может сделать из настроек телефона. На следующем рисунке показано, как пользователь может включить / отключить фоновую обработку для нашего приложения:
Вызов методов для создания / удаления нашей PeriodicTask из нашего обработчика событий Click, конечно, является простым действием, хотя вы должны заметить, что мы создаем PeriodicTask перед созданием вторичной плитки. Причина этого заключается в том, что PeriodicTask может отображать MessageBox для пользователя в случае возникновения проблем. Сначала создав Вторичную плитку, мы заставляем наше приложение немедленно перейти в фоновый режим, и при этом, не имея возможности показать MessageBox пользователю.
Агент запуска / остановки:
private void btnInstall_Click(object sender, RoutedEventArgs e) { if (secondaryTileInstalled) { var secondaryTile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileId=Secondary")); if (secondaryTile != null) { RemovePeriodicAgent(); secondaryTile.Delete(); btnInstall.Content = txtInstallTile; secondaryTileInstalled = false; } } else { StartPeriodicAgent(); StandardTileData NewTileData = new StandardTileData { BackgroundImage = new Uri("Background.png", UriKind.Relative), Title = "EvenTiles", Count = 0, BackBackgroundImage = new Uri("BackBackTile.png", UriKind.Relative), BackTitle = "EvenTiles", BackContent = App.ActualSecBackContent }; ShellTile.Create(new Uri("/MainPage.xaml?TileId=Secondary", UriKind.Relative), NewTileData); } }
Поскольку мы не добавили функциональность в нашу PeriodicTask, она будет активироваться каждые 30 минут, чтобы немедленно снова завершиться, потому что единственное, что мы делаем внутри метода OnInvoke PeriodicTask, — это вызов метода NotifyComplete:
Пустая периодическая задача:
protected override void OnInvoke(ScheduledTask task) { //TODO: Add code to perform your task in background NotifyComplete(); }
Я настоятельно рекомендую вам взглянуть на следующее видео, которое показывает все функциональные возможности, которые у нас есть в действии:
Одна вещь раздражает в нашем решении до сих пор. Если мы хотим отладить нашу PeriodicTask, нам придется каждый раз ждать 30 минут, пока код в PeriodicTask не будет выполнен. Как преодолеть эту проблему, будет тема части 11 нашей продолжающейся серии, посвященной EvenTiles.
Источник: http://mstruys.com/2011/12/21/eventiles-from-start-to-finishpart-10/