Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Remarque
Les listes de code de cette rubrique sont C# uniquement. Pour obtenir un exemple d’application App Service en C++/WinRT et C#, consultez l’exemple App Services ou obtenez la source des exemples de projets App Services sur GitHub.
Important
Cette rubrique s’applique aux applications de plateforme Windows universelle (UWP) qui utilisent .NET Native. Visual Studio 2022 inclut désormais également des modèles de projet UWP qui utilisent .NET 9. Pour cette rubrique, vous devez utiliser les modèles de projet UWP qui incluent « .NET Native » dans leurs noms, tels que l’application vide UWP (.NET Native). Les projets UWP qui utilisent .NET 9 n’ont pas été testés avec cette rubrique et peuvent ne pas fonctionner comme prévu.
Les services d’application sont des applications UWP qui fournissent des services à d’autres applications UWP. Ils sont analogues aux services web, sur un appareil. Un service d’application s’exécute en tant que tâche en arrière-plan dans l’application hôte et peut fournir son service à d’autres applications. Par exemple, un service d’application peut fournir un service de scanneur de codes barres que d’autres applications peuvent utiliser. Ou peut-être qu’une suite d’applications Enterprise dispose d’un service d’application de vérification orthographique courant qui est disponible pour les autres applications de la suite. Les services d’application vous permettent de créer des services sans interface utilisateur que les applications peuvent appeler sur le même appareil et à partir de Windows 10, version 1607, sur des appareils distants.
À compter de Windows 10, version 1607, vous pouvez créer des services d’application qui s’exécutent dans le même processus que l’application hôte. Cet article se concentre sur la création et la consommation d’un service d’application qui s’exécute dans un processus en arrière-plan distinct. Consultez Convertir un service d’application à exécuter dans le même processus que son application hôte pour plus d’informations sur l’exécution d’un service d’application dans le même processus que le fournisseur.
Créer un projet de fournisseur de service d'application
Dans ce guide pratique, nous allons créer tout dans une solution pour simplifier.
- Dans Visual Studio 2022 ou version ultérieure, créez un projet d’application UWP et nommez-le AppServiceProvider.
- Sélectionnez Fichier > Nouveau projet de >...
- Dans la boîte de dialogue Créer un projet , sélectionnez Application vide UWP (.NET Native). Veillez à sélectionner le type de projet C#. Il s’agit de l’application qui rend le service d’application disponible pour d’autres applications UWP.
- Cliquez sur suivant, puis nommez le projet AppServiceProvider, choisissez un emplacement pour celui-ci, puis cliquez sur Créer.
- Lorsque vous êtes invité à sélectionner un cible
et version minimale du projet, sélectionnez au moins10.0.14393 . Si vous souhaitez utiliser le nouvel attribut SupportsMultipleInstances , vous devez cibler 10.0.15063 (Windows 10 Creators Update) ou version ultérieure.
Ajouter une extension de service d'application à Package.appxmanifest
Dans le projet AppServiceProvider
- Cliquez avec le bouton droit sur celui-ci dans l’Explorateur de solutions .
- Sélectionnez Ouvrir avec.
- Sélectionnez éditeur XML (Texte).
Ajoutez l’extension AppService
suivante à l’intérieur de l’élément <Application>
. Cet exemple publie le service com.microsoft.inventory
et identifie cette application en tant que fournisseur de services d’application. Le service réel sera implémenté en tant que tâche en arrière-plan. Le projet App Service expose le service à d’autres applications. Nous vous recommandons d’utiliser un style de nom de domaine inverse pour le nom du service.
Notez que le préfixe d’espace de noms xmlns:uap4
et l’attribut uap4:SupportsMultipleInstances
sont valides uniquement si vous ciblez le SDK Windows version 10.0.15063 ou ultérieure. Vous pouvez les supprimer en toute sécurité si vous ciblez des versions antérieures du Kit de développement logiciel (SDK).
Remarque
Pour obtenir un exemple d’application App Service dans C++/WinRT et C#, consultez l'exemple d’application App Service .
<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>
L’attribut Category
identifie cette application en tant que fournisseur de services d'application et l’attribut EntryPoint
identifie la classe qualifiée par un espace de noms qui implémente le service. Nous allons implémenter cette prochaine étape.
L’attribut SupportsMultipleInstances
indique que chaque fois que le service d’application est appelé, il doit s’exécuter dans un nouveau processus. Cela n’est pas obligatoire, mais est disponible si vous avez besoin de cette fonctionnalité et ciblez le SDK 10.0.15063 (Windows 10 Creators Update) ou version ultérieure. Elle doit également être précédée par l’espace de noms uap4
.
Créer le service d’application
Dans cette section, nous allons créer un service d’application qui s’exécute en tant que tâche en arrière-plan. Le service d’application fournit un service d’inventaire simple qui permet à d’autres applications d’interroger le nom et le prix des éléments dans l’inventaire.
Un service d’application peut être implémenté en tant que tâche en arrière-plan. Cela permet à une application de premier plan d’appeler un service d’application dans une autre application. Pour créer un service d’application en tant que tâche en arrière-plan, ajoutez un nouveau projet de composant Windows Runtime à la solution (File > Add > New Project) nommé MyAppService. Dans la boîte de dialogue Ajouter un nouveau projet , choisissez Composant Windows Runtime (.NET Native).
Dans le projet AppServiceProvider, ajoutez une référence de projet au nouveau projet MyAppService (dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet AppServiceProvider, choisissez >>, > de la , sélectionnez >OK). Cette étape est essentielle, car si vous n’ajoutez pas la référence, le service d’application ne se connecte pas au moment de l’exécution.
Dans le projet MyAppService, ajoutez les suivantes à l’aide d’instructions en haut de Class1.cs:
using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Background; using Windows.Foundation.Collections;
Renommez Class1.cs en Inventory.cset remplacez le code stub pour classe1 par une nouvelle classe de tâche en arrière-plan nommée 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(); } } }
Cette classe est l’endroit où le service d’application fera son travail.
Run est appelée lorsque la tâche en arrière-plan est créée. Étant donné que les tâches en arrière-plan sont arrêtées une fois Exécuter terminées, le code supprime un report afin que la tâche en arrière-plan reste à jour pour traiter les demandes. Un service d’application implémenté en tant que tâche en arrière-plan reste actif pendant environ 30 secondes après qu’il reçoit un appel, sauf s’il est appelé à nouveau dans cette fenêtre de temps ou qu’un report est supprimé. Si le service d’application est implémenté dans le même processus que l’appelant, la durée de vie du service d’application est liée à la durée de vie de l’appelant.
La durée de vie du service d’application dépend de l’appelant :
- Si l’appelant est au premier plan, la durée de vie d’App Service est identique à celle de l’appelant.
- Si l’appelant est en arrière-plan, le service d’application obtient 30 secondes pour s’exécuter. L'utilisation d'un report offre une durée supplémentaire unique de 5 secondes.
OnTaskCanceled est appelée lorsque la tâche est annulée. La tâche est annulée lorsque l’application cliente supprime l'AppServiceConnection, l’application cliente est suspendue, le système d’exploitation est arrêté ou en veille, ou le système d’exploitation manque de ressources pour exécuter la tâche.
Écrire le code du service d’application
OnRequestReceived est l’emplacement où se trouve le code du service d’application. Remplacez le stub OnRequestReceived dans MyAppService's Inventory.cs par le code de cet exemple. Ce code obtient un index pour un élément d’inventaire et le transmet, ainsi qu’une chaîne de commande, au service pour récupérer le nom et le prix de l’élément d’inventaire spécifié. Pour vos propres projets, ajoutez du code de gestion des erreurs.
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();
}
}
Notez que OnRequestReceived est async car nous faisons un appel de méthode awaitable à SendResponseAsync dans cet exemple.
Un report est effectué afin que le service puisse utiliser méthodes asynchrones dans le gestionnaire OnRequestReceived. Il assure que l’appel à OnRequestReceived ne s'achève pas tant qu’il n’a pas terminé le traitement du message. SendResponseAsync envoie le résultat à l’appelant. sendResponseAsync ne signale pas l’achèvement de l’appel. Il s’agit de l’achèvement du report qui signale à SendMessageAsync que OnRequestReceived a terminé. L’appel à SendResponseAsync est encapsulé dans un bloc try/finally, car vous devez terminer le report même si SendResponseAsync lève une exception.
Les services d’application utilisent les objets valueset pour échanger des informations. La taille des données que vous pouvez transmettre n’est limitée que par les ressources système. Il n’existe aucune clé prédéfinie à utiliser dans votre ValueSet. Vous devez déterminer les valeurs clés que vous utiliserez pour définir le protocole de votre service d’application. L'appelant doit être écrit en tenant compte de ce protocole. Dans cet exemple, nous avons choisi une clé nommée Command
qui a une valeur qui indique si le service d’application doit fournir le nom de l’élément d’inventaire ou son prix. L’index du nom d’inventaire est stocké sous la clé ID
. La valeur de retour est stockée sous la clé Result
.
Une énumération AppServiceClosedStatus est retournée à l’appelant pour indiquer si l’appel au service d’application a réussi ou échoué. Par exemple, l’appel au service d’application peut échouer si le système d’exploitation abandonne le point de terminaison de service, car ses ressources ont été dépassées. Vous pouvez retourner des informations d’erreur supplémentaires via le ValueSet. Dans cet exemple, nous utilisons une clé nommée Status
pour renvoyer des informations d’erreur plus détaillées à l’appelant.
L’appel à SendResponseAsync retourne le ValueSet à l’appelant.
Déployer l’application de service et obtenir le nom de la famille de packages
Le fournisseur de service d'application doit être déployé avant que vous puissiez l'appeler à partir d’un client. Vous pouvez le déployer en sélectionnant Build > Deploy Solution dans Visual Studio.
Vous aurez également besoin du nom de famille du package du fournisseur de service d'application pour pouvoir l'appeler. Vous pouvez l’obtenir en procédant comme suit :
- Ouvrez le fichier Package.appxmanifest du projet AppServiceProvider en mode Concepteur (double-cliquez dessus dans l’Explorateur de solutions).
- Sélectionnez l’onglet Emballage, copiez la valeur à côté de nom de famille du package, puis collez-la dans un endroit comme le Bloc-notes pour le moment.
Écrire un client pour appeler le service d’application
Dans cette section, nous allons créer une application cliente qui appelle le service d’application que nous venons de créer. L’application cliente est une application UWP simple qui a une zone de texte et un bouton. Lorsque l’utilisateur entre un index dans la zone de texte et clique sur le bouton, l’application appelle le service d’application pour obtenir le nom et le prix de l’élément d’inventaire à cet index.
Ajoutez un nouveau projet d’application Windows Universelle vide à la solution avec Fichier > Ajouter > Nouveau Projet. Dans la boîte de dialogue Ajouter un nouveau projet , choisissez Application vide UWP (.NET Native) et nommez-la ClientApp.
Dans le projet ClientApp, ajoutez la suivante à l’aide de l’instruction en haut de MainPage.xaml.cs:
using Windows.ApplicationModel.AppService;
Remplacez la grille sur la page principale par un StackPanel afin que nous puissions y ajouter une zone de texte et un bouton.
Ajoutez une zone de texte nommée textBox et un bouton à MainPage.xaml.
Ajoutez un bouton avec un gestionnaire d’événements Click appelé button_Click et du texte pour le contenu tel que « Cliquez sur moi ».
Ajoutez le mot clé asynchrone à la signature du gestionnaire de boutons dans MainPage.xaml.cs.
Remplacez le stub de votre gestionnaire de clics de bouton par le code suivant. Veillez à inclure la déclaration de champ
inventoryService
dans la classe.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; }
Remplacez le nom de la famille de packages dans la ligne
this.inventoryService.PackageFamilyName = "Replace with the package family name";
par le nom de famille de package du projet AppServiceProvider que vous avez obtenu ci-dessus dans Déployer l’application de service et obtenir le nom de famille de package.Remarque
Veillez à coller la chaîne de caractères littérale, plutôt qu'à la mettre dans une variable. Cela ne fonctionnera pas si vous utilisez une variable.
Le code établit d’abord une connexion avec le service d’application. La connexion reste ouverte jusqu’à ce que vous utilisiez
this.inventoryService
. Le nom du service d’application doit correspondre à l’attributAppService
de l’élémentName
que vous avez ajouté au fichier AppServiceProvider projet Package.appxmanifest. Dans cet exemple, il s’agit de<uap3:AppService Name="com.microsoft.inventory"/>
.Un ValueSet nommé
message
est créé pour spécifier la commande que nous voulons envoyer au service d’application. L’exemple d’app service s’attend à ce qu’une commande indique les deux actions à entreprendre. Nous obtenons l’index à partir de la zone de texte de l’application cliente, puis appelons le service avec la commandeItem
pour obtenir la description de l’élément. Ensuite, nous effectuons l’appel avec la commandePrice
pour obtenir le prix de l’article. Le texte du bouton est attribué au résultat.Étant donné que AppServiceResponseStatus indique uniquement si le système d’exploitation a pu connecter l’appel au service d’application, nous vérifions la clé
Status
dans la ValueSet que nous recevons du service d’application pour vous assurer qu’il a été en mesure de répondre à la demande.Définissez le projet ClientApp
comme projet de démarrage (cliquez avec le bouton droit sur celui-ci dans l’Explorateur de solutions définir comme projet de démarrage ) et exécutez la solution. Entrez le numéro 1 dans la zone de texte, puis cliquez sur le bouton. Vous devriez obtenir « Chair : Prix = 88,99 » en retour du service.
Résoudre les problèmes courants
Si l’appel app service échoue, vérifiez ce qui suit dans le projet ClientApp :
- Vérifiez que le nom de la famille de packages attribué à la connexion du service d’inventaire correspond au nom de famille de package de l’application AppServiceProvider. Voir la ligne dans le bouton "button_Click" avec
this.inventoryService.PackageFamilyName = "...";
. - Dans button_Click, vérifiez que le nom du service d’application affecté à la connexion du service d’inventaire correspond au nom du service d’application dans le fichier AppServiceProvider's Package.appxmanifest. Voir :
this.inventoryService.AppServiceName = "com.microsoft.inventory";
. - Vérifiez que l’application AppServiceProvider a été déployée. (Dans l’Explorateur de solutions , cliquez avec le bouton droit sur la solution et choisissez Déployer la solution).
Déboguer le service d’application
Pour déboguer le service d’application, vous devez configurer la solution afin que le fournisseur app service soit déployé et que le service d’application puisse être appelé à partir de l’application cliente. Suivez ces étapes :
- Vérifiez que la solution est déployée avant le débogage, car l’application du fournisseur app service doit être déployée avant que le service puisse être appelé. (Dans Visual Studio, générer > déployer la solution).
- Dans lede l’Explorateur de solutions
, cliquez avec le bouton droit sur le projet AppServiceProvider de débogageet choisissez Propriétés . À partir de l’onglet, modifiez l' action Démarrer en Ne pas lancer, mais déboguer mon code au démarrage . (Notez que si vous utilisiez C++ pour implémenter votre fournisseur App Service, à partir de l’onglet Débogage, vous devez modifier Lancer l'application en Non). - Dans le projet MyAppService
, dans le fichier Inventory.cs , définissez un point d’arrêt dansOnRequestReceived . - Définissez le projet AppServiceProvider comme projet de démarrage et appuyez sur F5.
- Démarrez ClientApp à partir du menu Démarrer (pas à partir de Visual Studio).
- Entrez le numéro 1 dans la zone de texte et appuyez sur le bouton. Le débogueur s'arrêtera pendant l'appel au service d'application sur le point d'arrêt de votre service d'application.
Déboguer le client
Pour déboguer l’application cliente qui appelle le service d’application, vous devez attacher le débogueur au processus d’application cliente. Suivez ces étapes :
- Suivez les instructions de l’étape précédente pour déboguer le client qui appelle le service d’application.
- Lancez ClientApp à partir du menu Démarrer.
- Attachez le débogueur au processus ClientApp.exe (et non pas au processus ApplicationFrameHost.exe). (Dans Visual Studio, choisissez Déboguer > S'attacher à un processus....)
- Dans le projet ClientApp, définissez un point d’arrêt dans button_Click.
- Les points d’arrêt du client et du service d’application sont désormais atteints lorsque vous entrez le numéro 1 dans la zone de texte de ClientApp, puis cliquez sur le bouton.
Résolution des problèmes généraux du service d’application
Si vous rencontrez un état AppUnavailable après avoir essayé de vous connecter à un service d’application, vérifiez ce qui suit :
- Vérifiez que le projet du fournisseur d’application et le projet App Service sont déployés. Les deux doivent être déployés avant d’exécuter le client, sinon ce dernier n’aura rien avec quoi se connecter. Vous pouvez déployer à partir de Visual Studio à l’aide de Build>Deploy Solution.
- Dans l’Explorateur de solutions , vérifiez que votre projet de fournisseur d’applications dispose d’une référence de projet à projet au projet qui implémente le service d’application.
- Vérifiez que l’entrée
<Extensions>
et ses éléments enfants ont été ajoutés au fichier Package.appxmanifest appartenant au projet du fournisseur de service d'application, comme indiqué ci-dessus dans Ajouter une extension de service d'application à Package.appxmanifest. - Vérifiez que la chaîne AppServiceConnection.AppServiceName dans votre client qui appelle le fournisseur d’applications correspond à la
<uap3:AppService Name="..." />
spécifiée dans le fichier Package.appxmanifest du projet du fournisseur d’applications. - Vérifiez que l'AppServiceConnection.PackageFamilyName correspond au nom de famille de package du composant du fournisseur d’applications tel que spécifié ci-dessus dans Ajouter une extension app service à Package.appxmanifest
- Pour les services d’application hors processus, tels que celui de cet exemple, vérifiez que le
spécifié dans l’élément du fichier Package.appxmanifest du projet de fournisseur de services d'application correspond à l’espace de noms et au nom de classe de la classe publique qui implémente IBackgroundTask dans votre projet de service d'application.
Résoudre les problèmes de débogage
Si le débogueur ne s’arrête pas aux points d’arrêt dans votre fournisseur de services d'application ou vos projets de services d'application, consultez les éléments suivants :
- Vérifiez que le projet du fournisseur d’application et le projet App Service sont déployés. Tous les deux doivent être déployés avant d’exécuter le client. Vous pouvez les déployer à partir de Visual Studio à l’aide de Build>Deploy Solution.
- Vérifiez que le projet que vous souhaitez déboguer est défini comme projet de démarrage et que les propriétés de débogage de ce projet sont configurées pour ne pas exécuter le projet lorsque F5 est enfoncée. Cliquez avec le bouton droit sur le projet, puis cliquez sur Propriétés, et ensuite Débogage (ou Débogage en C++). En C#, modifiez l’action Démarrer pour Ne pas lancer, mais déboguer mon code quand il démarre. Dans C++, réglez Lancer l’Application sur Aucun.
Remarques
Cet exemple fournit une introduction à la création d’un service d’application qui s’exécute en tant que tâche en arrière-plan et l’appelant à partir d’une autre application. Les éléments clés à noter sont les suivants :
- Créez une tâche en arrière-plan pour héberger le service d’application.
- Ajoutez l’extension
windows.appService
au fichier Package.appxmanifest du fournisseur de services d'applications. - Obtenez le nom de famille du package du fournisseur de service d'application afin que nous puissions nous y connecter à partir de l'application cliente.
- Ajoutez une référence de projet à projet du projet de fournisseur de service d'application au projet de service d'application.
- Utilisez Windows.ApplicationModel.AppService.AppServiceConnection pour appeler le service.
Code complet pour MyAppService
Voici le code complet du projet MyAppService , qui implémente le service d’application en tant que tâche en arrière-plan. Ce code doit être placé dans le fichier Inventory.cs du projet 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();
}
}
}
}