Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
Список кода в этом разделе — это только C#. Пример приложения для службы приложений на C++/WinRT и C# можно найти в примере служб приложений или скачать исходные код проектов примера служб приложений на GitHub.
Это важно
Этот раздел относится к приложениям универсальной платформы Windows (UWP), использующим .NET Native. Visual Studio 2022 теперь также включает шаблоны проектов UWP, использующие .NET 9. По этой теме необходимо использовать шаблоны проектов UWP, которые включают .NET Native в названиях, например UWP Blank App (.NET Native). Проекты UWP, использующие .NET 9, не были протестированы с помощью этого раздела и могут не работать должным образом.
Службы приложений — это приложения UWP, предоставляющие службы другим приложениям UWP. Они аналогичны веб-службам на устройстве. Служба приложений выполняется в качестве фоновой задачи в хост-приложении и может предоставлять свою службу другим приложениям. Например, служба приложений может предоставить службу сканера штрих-кода, которую могут использовать другие приложения. Или, возможно, набор приложений Enterprise имеет общую службу проверки орфографии, доступную другим приложениям в наборе. Службы приложений позволяют создавать службы без пользовательского интерфейса, которые приложения могут вызывать на одном устройстве и начиная с Windows 10 версии 1607 на удаленных устройствах.
Начиная с Windows 10 версии 1607, можно создать службы приложений, которые выполняются в том же процессе, что и ведущее приложение. В этой статье рассматривается создание и использование службы приложений, которая выполняется в отдельном фоновом процессе. См. в , чтобы узнать больше о запуске службы приложений в том же процессе, что и ведущее приложение, и в, чтобы узнать о запуске службы в том же процессе, что и поставщик.
Создание проекта поставщика службы приложений
В этом руководстве мы создадим все в одном решении для простоты.
- В Visual Studio 2022 или более поздней версии создайте проект приложения UWP и назовите его AppServiceProvider.
- Выберите Файл > Новый > Проект...
- В диалоговом окне "Создание проекта" выберите пустоеприложение UWP (.NET Native). Обязательно выберите тип проекта C#. Это будет приложение, которое делает службу приложений доступной для других приложений UWP.
- Щелкните Далее, затем назовите проект AppServiceProvider, выберите его расположение и нажмите Создать.
- Когда будет предложено выбрать целевую версию и минимальную версию для проекта, выберите версию не менее чем 10.0.14393. Если вы хотите использовать новый атрибут SupportsMultipleInstances , необходимо выбрать 10.0.15063 (Windows 10 Creators Update) или более поздней версии.
Добавление расширения службы приложений в Package.appxmanifest
В проекте AppServiceProvider откройте файл Package.appxmanifest в текстовом редакторе.
- Щелкните его правой кнопкой мыши в обозревателе решений.
- Выберите Открыть с помощью.
- Выберите редактор XML (текст).
Добавьте следующее расширение AppService
внутри элемента <Application>
. В этом примере рекламируется служба com.microsoft.inventory
и это приложение идентифицируется как поставщик услуг приложений. Сама служба будет реализована как фоновая задача. Проект службы приложений предоставляет службу другим приложениям. Рекомендуем использовать стиль обратного доменного имени для названия сервиса.
Обратите внимание, что префикс пространства имен xmlns:uap4
и атрибут uap4:SupportsMultipleInstances
допустимы только если вы используете Windows SDK версии 10.0.15063 или более поздней. Их можно безопасно удалить, если вы используете более старые версии пакета SDK.
Замечание
Для примера приложения службы приложений в C++/WinRT, а также на C#, см. пример приложения службы приложений в .
<Package
...
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
...
<Applications>
<Application Id="AppServiceProvider.App"
Executable="$targetnametoken$.exe"
EntryPoint="AppServiceProvider.App">
...
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="MyAppService.Inventory">
<uap3:AppService Name="com.microsoft.inventory" uap4:SupportsMultipleInstances="true"/>
</uap:Extension>
</Extensions>
...
</Application>
</Applications>
Атрибут Category
определяет это приложение как поставщик службы приложений, а EntryPoint
атрибут определяет квалифицированный класс пространства имен, реализующий службу. Далее мы это реализуем.
Атрибут SupportsMultipleInstances
указывает, что каждый раз, когда служба приложений вызывается, что она должна выполняться в новом процессе. Это не обязательно, но доступно для вас, если вам нужна эта функция и предназначена для пакета SDK 10.0.15063 (Windows 10 Creators Update) или более поздней версии. Это также должно начинаться с пространства имен uap4
.
Создание службы приложений
В этом разделе мы создадим службу приложений, которая выполняется в качестве фоновой задачи. Служба приложений предоставляет простую службу инвентаризации, которая позволяет другим приложениям запрашивать имя и стоимость элементов в инвентаризации.
Служба приложений может быть реализована как фоновая задача. Это позволяет приложению переднего плана вызывать службу приложений в другом приложении. Чтобы создать службу приложений в качестве фоновой задачи, добавьте новый проект компонента среды выполнения Windows в решение (добавление нового проекта файла >>) с именем MyAppService. В диалоговом окне "Добавление нового проекта " выберите компонент среды выполнения Windows (.NET Native).
В проекте AppServiceProvider добавьте ссылку на проект MyAppService (в обозревателе решений щелкните правой кнопкой мыши проект >Add>Reference>Projects> Solution, выберитеMyAppService>OK). Этот шаг является критическим, так как если вы не добавите ссылку, служба приложений не будет подключаться во время выполнения.
В проекте MyAppService добавьте следующие директивы using в начало файла Class1.cs:
using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Background; using Windows.Foundation.Collections;
Переименуйте Class1.cs на Inventory.csи замените код заглушки для class1 новым классом фоновой задачи с именем Inventory:
public sealed class Inventory : IBackgroundTask { private BackgroundTaskDeferral backgroundTaskDeferral; private AppServiceConnection appServiceconnection; private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" }; private double[] inventoryPrices = new double[] { 129.99, 88.99 }; public void Run(IBackgroundTaskInstance taskInstance) { // Get a deferral so that the service isn't terminated. this.backgroundTaskDeferral = taskInstance.GetDeferral(); // Associate a cancellation handler with the background task. taskInstance.Canceled += OnTaskCanceled; // Retrieve the app service connection and set up a listener for incoming app service requests. var details = taskInstance.TriggerDetails as AppServiceTriggerDetails; appServiceconnection = details.AppServiceConnection; appServiceconnection.RequestReceived += OnRequestReceived; } private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { // This function is called when the app service receives a request. } private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { if (this.backgroundTaskDeferral != null) { // Complete the service deferral. this.backgroundTaskDeferral.Complete(); } } }
Этот класс находится в том месте, где служба приложений будет выполнять свою работу.
Функция Run вызывается при создании фоновой задачи. Поскольку фоновые задачи завершаются после завершения выполнения, код получает отсрочку, чтобы фоновая задача продолжала выполняться для обслуживания запросов. Служба приложений, реализованная как фоновая задача, будет продолжать работать около 30 секунд после получения вызова, если она не вызывается снова в течение этого времени или взята отсрочка. Если служба приложений реализована в том же процессе, что и вызывающий объект, время её работы привязано ко времени работы вызывающего объекта.
Время существования службы приложений зависит от вызывающего объекта:
- Если вызывающий объект находится на переднем плане, время работы службы приложения совпадает с временем работы вызывающего объекта.
- Если вызывающий объект находится в фоновом режиме, служба приложений получает 30 секунд для запуска. Применение отсрочки предоставляет дополнительное одноразовое 5 секунд.
При отмене задачи вызывается onTaskCanceled. Задача отменяется, когда клиентское приложение удаляет AppServiceConnection, клиентское приложение находится в спящем режиме, операционная система завершает работу или переходит в спящий режим, или операционной системе не хватает ресурсов для выполнения задачи.
Написание кода для службы приложений
OnRequestReceived — это место, куда помещается код для службы приложений. Замените заглушку OnRequestReceived в MyAppServiceInventory.cs кодом из этого примера. Этот код получает индекс для элемента инвентаризации и передает его вместе с командной строкой в службу, чтобы получить имя и цену указанного элемента инвентаризации. Для собственных проектов добавьте код обработки ошибок.
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// Get a deferral because we use an awaitable API below to respond to the message
// and we don't want this call to get canceled while we are waiting.
var messageDeferral = args.GetDeferral();
ValueSet message = args.Request.Message;
ValueSet returnData = new ValueSet();
string command = message["Command"] as string;
int? inventoryIndex = message["ID"] as int?;
if (inventoryIndex.HasValue &&
inventoryIndex.Value >= 0 &&
inventoryIndex.Value < inventoryItems.GetLength(0))
{
switch (command)
{
case "Price":
{
returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
case "Item":
{
returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
default:
{
returnData.Add("Status", "Fail: unknown command");
break;
}
}
}
else
{
returnData.Add("Status", "Fail: Index out of range");
}
try
{
// Return the data to the caller.
await args.Request.SendResponseAsync(returnData);
}
catch (Exception e)
{
// Your exception handling code here.
}
finally
{
// Complete the deferral so that the platform knows that we're done responding to the app service call.
// Note for error handling: this must be called even if SendResponseAsync() throws an exception.
messageDeferral.Complete();
}
}
Обратите внимание, что OnRequestReceived является асинхронным, потому что мы вызываем ожидающий метод SendResponseAsync в этом примере.
Чтобы служба могла использовать асинхронные методы в обработчике OnRequestReceived, предусмотрена отсрочка. Это гарантирует, что вызов OnRequestReceived не завершается, пока не завершится обработка сообщения. SendResponseAsync отправляет результат вызывающему. SendResponseAsync не сигнализирует о завершении вызова. Это завершение отсрочки, которое сигнализирует SendMessageAsync о том, что OnRequestReceived завершено. Вызов SendResponseAsync упакован в блок try/finally, так как необходимо завершить отсрочку, даже если SendResponseAsync вызывает исключение.
Службы приложений используют объекты ValueSet для обмена информацией. Размер данных, которые можно передать, ограничен только системными ресурсами. В наборе значений нет предопределенных ключей. Необходимо определить, какие ключевые значения будут использоваться для определения протокола для службы приложений. Вызывающий объект должен быть создан с учетом этого протокола. В этом примере мы выбрали ключ с именем Command
, который имеет значение, указывающее, нужно ли предоставить службе приложений имя элемента инвентаризации или его цены. Индекс наименования инвентаря хранится под ключом ID
. Возвращаемое значение хранится под ключом Result
.
Перечисление AppServiceClosedStatus возвращается вызывающему объекту, чтобы указать, выполнен ли вызов службы приложений успешно или завершился ошибкой. Пример того, как вызов службы приложений может завершиться сбоем, если ОС прерывает конечную точку службы, так как ее ресурсы были превышены. Дополнительные сведения об ошибке можно вернуть с помощью ValueSet. В этом примере мы используем ключ с именем Status
для передачи более подробной информации об ошибке вызывающему объекту.
Вызов
Развертывание приложения-службы и получение имени семейства пакетов
Прежде чем вы сможете вызвать службу приложений с клиента, необходимо развернуть её. Вы можете развернуть его, выбрав Сборка > Развернуть решение в Visual Studio.
Вам также потребуется имя семейства пакетов поставщика службы приложений, чтобы вызвать его. Чтобы получить его, сделайте следующее:
- Откройте файл Package.appxmanifest проекта AppServiceProvider в представлении конструктора (дважды щелкните его в обозревателе решений).
- Выберите вкладку Упаковка, скопируйте значение рядом с имя семейства пакетови вставьте его где-то, вроде приложения Блокнот.
Создание клиента для вызова службы приложений
В этом разделе мы создадим клиентское приложение, которое вызывает только что созданную службу приложений. Клиентское приложение будет простым приложением UWP с текстовым полем и кнопкой. Когда пользователь вводит индекс в текстовое поле и нажимает кнопку, приложение вызовет службу приложений, чтобы получить имя и цену элемента инвентаризации по этому индексу.
Добавьте в решение новый пустой проект универсального приложения Windows через Файл Добавить > Новый проект >. В диалоговом окне "Добавление нового проекта" выберите пустое приложение UWP (.NET Native) и назовите его ClientApp.
В проекте ClientApp добавьте следующий с помощью инструкции в начало MainPage.xaml.cs:
using Windows.ApplicationModel.AppService;
Измените Grid на главной странице на StackPanel, чтобы добавить в него текстовое поле и кнопку.
Добавьте текстовое поле с именем textBox и кнопку в MainPage.xaml.
Добавьте кнопку с обработчиком событий щелчка с именем button_Click и текстом для содержимого, например "Щелкните меня".
Добавьте асинхронное ключевое слово в подпись обработчика кнопки в MainPage.xaml.cs.
Замените заглушку обработчика нажатия кнопки следующим кодом. Не забудьте включить объявление поля
inventoryService
в класс.private AppServiceConnection inventoryService; private async void button_Click(object sender, RoutedEventArgs e) { // Add the connection. if (this.inventoryService == null) { this.inventoryService = new AppServiceConnection(); // Here, we use the app service name defined in the app service // provider's Package.appxmanifest file in the <Extension> section. this.inventoryService.AppServiceName = "com.microsoft.inventory"; // Use Windows.ApplicationModel.Package.Current.Id.FamilyName // within the app service provider to get this value. this.inventoryService.PackageFamilyName = "Replace with the package family name"; var status = await this.inventoryService.OpenAsync(); if (status != AppServiceConnectionStatus.Success) { textBox.Text= "Failed to connect"; this.inventoryService = null; return; } } // Call the service. int idx = int.Parse(textBox.Text); var message = new ValueSet(); message.Add("Command", "Item"); message.Add("ID", idx); AppServiceResponse response = await this.inventoryService.SendMessageAsync(message); string result = ""; if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result = response.Message["Result"] as string; } } message.Clear(); message.Add("Command", "Price"); message.Add("ID", idx); response = await this.inventoryService.SendMessageAsync(message); if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result += " : Price = " + response.Message["Result"] as string; } } textBox.Text = result; }
Замените имя семейства пакетов в строке
this.inventoryService.PackageFamilyName = "Replace with the package family name";
на имя семейства пакетов проекта AppServiceProvider, полученное выше в шаге , разверните приложение-службу и получите имя семейства пакетов.Замечание
Не забудьте вставить строковый литерал, а не поместить его в переменную. Он не будет работать, если вы используете переменную.
Код сначала устанавливает подключение к службе приложений. Подключение останется открытым, пока не будет удалено
this.inventoryService
. Имя службы приложений должно соответствовать атрибутуAppService
элементаName
, добавленного в файл AppServiceProvider проекта Package.appxmanif est. В этом примере это<uap3:AppService Name="com.microsoft.inventory"/>
.Создается
ValueSet с именем , чтобы указать команду, которую мы хотим отправить в службу приложений. В примере службы приложений ожидается, что команда указывает, какие из двух действий необходимо выполнить. Мы получаем индекс из текстового поля в клиентском приложении, а затем вызовем службу с Item
помощью команды, чтобы получить описание элемента. Затем мы вызываем командуPrice
, чтобы получить цену элемента. Текст кнопки имеет значение результата.Так как AppServiceResponseStatus указывает, удалось ли операционной системе соединить вызов со службой приложений, мы проверяем ключ
Status
в ValueSet, который мы получаем от службы приложений, чтобы убедиться, что она смогла выполнить запрос.Задайте проект ClientApp в качестве проекта запуска (щелкните его правой кнопкой мыши в Обозревателе решений >Задать как проект запуска) и запустите решение. Введите номер 1 в текстовое поле и нажмите кнопку. Вы должны получить "Кресло: Цена = 88,99" обратно от службы.
Устранение распространенных проблем
Если вызов службы приложений завершается сбоем, проверьте следующее в проекте ClientApp :
- Убедитесь, что имя семейства пакетов, назначенное подключению службы инвентаризации, соответствует имени семейства пакетов приложения AppServiceProvider . Посмотрите строку в button_Click с
this.inventoryService.PackageFamilyName = "...";
. - В button_Clickубедитесь, что имя службы приложений, назначенное подключению службы инвентаризации, соответствует имени службы приложений в файле AppServiceProviderPackage.appxmanifest. См.
this.inventoryService.AppServiceName = "com.microsoft.inventory";
. - Убедитесь, что приложение AppServiceProvider развернуто. (В обозревателе решенийщелкните правой кнопкой мыши на решении и выберите Развернуть решение).
Отладка службы приложений
Чтобы отладить службу приложений, необходимо настроить решение таким образом, чтобы поставщик службы приложений был развернут и служба приложений может вызываться из клиентского приложения. Выполните следующие действия.
- Убедитесь, что решение развертывается перед отладкой, так как приложение поставщика службы приложений должно быть развернуто перед вызовом службы. (В Visual Studio Построение решения > Развертывание решения).
- В обозревателе решений
щелкните правой кнопк ой мыши проект AppServiceProvider и выберитесвойства . На вкладкеОтладка измените действия запускана Не запускайте, а отладите код при запуске . (Обратите внимание, что если бы вы использовали C++ для реализации вашего поставщика услуг приложений, на вкладке "Отладка" вы бы изменили "Запуск приложения" на "Нет"). - В проекте MyAppService в файле Inventory.cs установите точку останова в OnRequestReceived.
- Задайте для проекта
AppServiceProvider и нажмите клавишу F5 F5. - Запустите ClientApp из меню "Пуск" (не из Visual Studio).
- Введите номер 1 в текстовое поле и нажмите кнопку. Отладчик остановится на вызове вашего приложения в точке останова службы приложений.
Отладка клиента
Чтобы отладить клиентское приложение, которое вызывает службу приложений, необходимо подключить отладчик к процессу клиентского приложения. Выполните следующие действия.
- Следуйте инструкциям на предыдущем шаге, чтобы выполнить отладку клиента, вызывающего службу приложений.
- Запустите ClientApp из меню "Пуск".
- Подключите отладчик к процессу ClientApp.exe (а не к процессу ApplicationFrameHost.exe ). (В Visual Studio выберите Отладка > присоединение к процессу....)
- В проекте ClientApp установите точку останова в button_Click.
- Точки останова в клиенте и службе приложений будут достигнуты, когда вы введете число 1 в текстовое поле ClientApp и нажмете кнопку.
Устранение неполадок с службой приложений общего характера
Если после попытки подключения к службе приложения появляется статус AppUnavailable, проверьте следующее:
- Убедитесь, что проект поставщика службы приложений и проект службы приложений развернуты. Перед запуском клиента необходимо развернуть оба элемента, так как в противном случае у клиента не будет ничего, к чему подключиться. Вы можете развернуть из Visual Studio, используя сборку >развертывание решения.
- В обозревателе решенийубедитесь, что проект вашего поставщика службы приложений имеет ссылку на проект, реализующий эту службу.
- Убедитесь, что
<Extensions>
запись и её дочерние элементы были добавлены в файл Package.appxmanifest, принадлежащий проекту поставщика службы приложений, как указано выше в Добавить расширение службы приложений в Package.appxmanifest. - Убедитесь, что строка AppServiceConnection.AppServiceName в клиенте, вызывающая поставщика службы приложений, соответствует
<uap3:AppService Name="..." />
, указанному в файле Package.appxmanifest проекта поставщика службы приложений. - Убедитесь, что AppServiceConnection.PackageFamilyName соответствует имени семейства пакетов компонента поставщика службы приложений, как указано выше в разделе "Добавление расширения службы приложений в Package.appxmanifest"
- Для внепроцессных служб приложений, таких как в этом примере, убедитесь, что
EntryPoint
, указанный в атрибуте<uap:Extension ...>
проекта вашего провайдера сервисов приложений, Package.appxmanifest соответствует пространству имен и имени класса публичного класса, реализующего IBackgroundTask в проекте службы приложений.
Отладка и устранение неполадок
Если отладчик не останавливается в точках останова в проектах поставщика служб приложений или службы приложений, проверьте следующее:
- Убедитесь, что проект поставщика службы приложений и проект службы приложений развернуты. Перед запуском клиента необходимо развернуть оба. Их можно развернуть из Visual Studio с помощью сборки>развернуть решение.
- Убедитесь, что проект, который требуется отладить, задан в качестве запускаемого проекта и что свойства отладки для этого проекта не запускаются при нажатии клавиши F5 . Щелкните правой кнопкой мыши на проекте, затем Свойстваи потом Отладка (или Отладка в C++). В C# измените действие запуска на Не запускайте, а отлаживайте мой код при запуске. В C++ задайте запуск приложения значением Нет.
Замечания
В этом примере представлено введение в создание службы приложений, которая выполняется в качестве фоновой задачи и вызывает ее из другого приложения. Основные моменты, которые следует отметить:
- Создайте фоновую задачу для размещения службы приложений.
- Добавьте расширение
windows.appService
в файл Package.appxmanifest поставщика службы приложений. - Получите имя семейства пакетов поставщика приложений, чтобы подключиться к нему из клиентского приложения.
- Добавьте ссылку с проекта поставщика службы приложений на проект службы приложений.
- Используйте Windows.ApplicationModel.AppService.AppServiceConnection для вызова службы.
Полный код для MyAppService
Ниже приведен полный код для проекта MyAppService , который реализует службу приложений в качестве фоновой задачи. Этот код должен быть помещен в файл Inventory.cs проекта MyAppService .
using System;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;
namespace MyAppService
{
public sealed class Inventory : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private AppServiceConnection appServiceconnection;
private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" };
private double[] inventoryPrices = new double[] { 129.99, 88.99 };
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get a deferral so that the service isn't terminated.
this.backgroundTaskDeferral = taskInstance.GetDeferral();
// Associate a cancellation handler with the background task.
taskInstance.Canceled += OnTaskCanceled;
// Retrieve the app service connection and set up a listener for incoming app service requests.
var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
appServiceconnection = details.AppServiceConnection;
appServiceconnection.RequestReceived += OnRequestReceived;
}
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// Get a deferral because we use an awaitable API below to respond to the message
// and we don't want this call to get canceled while we are waiting.
var messageDeferral = args.GetDeferral();
ValueSet message = args.Request.Message;
ValueSet returnData = new ValueSet();
string command = message["Command"] as string;
int? inventoryIndex = message["ID"] as int?;
if (inventoryIndex.HasValue &&
inventoryIndex.Value >= 0 &&
inventoryIndex.Value < inventoryItems.GetLength(0))
{
switch (command)
{
case "Price":
{
returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
case "Item":
{
returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
default:
{
returnData.Add("Status", "Fail: unknown command");
break;
}
}
}
else
{
returnData.Add("Status", "Fail: Index out of range");
}
// Return the data to the caller.
await args.Request.SendResponseAsync(returnData);
// Complete the deferral so that the platform knows that we're done responding to the app service call.
// Note for error handling: this must be called even if SendResponseAsync() throws an exception.
messageDeferral.Complete();
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
if (this.backgroundTaskDeferral != null)
{
// Complete the service deferral.
this.backgroundTaskDeferral.Complete();
}
}
}
}