Creare e utilizzare un servizio app

Importante

Gli elenchi di codice in questo argomento sono solo C#. Per un'app di esempio del servizio app in C++/WinRT e C#, vedere App di esempio del servizio app.

I servizi app sono app UWP che forniscono servizi ad altre app UWP. Sono analoghi ai servizi Web in un dispositivo. Un servizio app è eseguito come attività in background nell'app host e può fornire il proprio servizio ad altre app. Ad esempio, un servizio app potrebbe fornire un servizio scanner di codice a barre utilizzabile da altre app. O forse una suite enterprise di app ha un servizio app di controllo ortografico comune disponibile per le altre app nella suite. I servizi app consentono di creare servizi senza interfaccia utente che le app possono chiamare sullo stesso dispositivo e a partire da Windows 10, versione 1607, nei dispositivi remoti.

A partire da Windows 10 versione 1607, è possibile creare servizi app eseguiti nello stesso processo dell'app host. Questo articolo è incentrato sulla creazione e l'utilizzo di un servizio app eseguito in un processo in background separato. Per altri dettagli sull'esecuzione di un servizio app nello stesso processo dell'app host, vedere Convertire un servizio app nello stesso processo del provider.

Creare un nuovo progetto del provider di servizi app

Per semplicità, in questa guida, creeremo tutti gli elementi in un'unica soluzione.

  1. In Visual Studio 2015 o versione successiva creare un nuovo progetto di app UWP e denominarlo AppServiceProvider.

    1. Select File > Nuovo > Progetto...
    2. Nella finestra di dialogo Crea un nuovo progetto seleziona App vuota (Windows universal) C#. Questa sarà l'app che rende il servizio app disponibile per altre app UWP.
    3. Fare clic su Avanti, quindi assegnare al progetto il nome AppServiceProvider, scegliere un percorso e quindi fare clic su Crea.
  2. Quando viene chiesto di selezionare una versione Target e Minima per il progetto, selezionare almeno 10.0.14393. Se si vuole usare il nuovo attributo SupportsMultipleInstances, è necessario usare Visual Studio 2017 o Visual Studio 2019 e 10.0.15063 (Windows 10 Creators Update) o versione successiva.

Aggiungere un'estensione del servizio app a Package.appxmanifest

Nel progetto AppServiceProvider aprire il file Package.appxmanifest in un editor di testo:

  1. Fare clic con il tasto destro del mouse in Esplora soluzioni.
  2. Selezionare Apri con.
  3. Selezionare Editor XML (testo).

Aggiungere la seguente AppService estensione <Application> nell'elemento. Questo esempio annuncia il servizio com.microsoft.inventory ed è ciò che identifica questa app come provider di servizi app. Il servizio effettivo verrà implementato come attività in background. Il progetto del servizio app espone il servizio ad altre app. È consigliabile usare uno stile di nome di dominio inverso per il nome del servizio.

Si noti che il prefisso xmlns:uap4 dello spazio dei nomi e l'attributo uap4:SupportsMultipleInstances sono validi solo se si ha come destinazione Windows SDK versione 10.0.15063 o successiva. È possibile rimuoverli in modo sicuro se si hanno come destinazione le versioni precedenti dell'SDK.

Nota

Per un'app di esempio del servizio app in C++/WinRT e C#, vedere App di esempio del servizio app.

<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'attributo Category identifica questa applicazione come provider di servizi app.

L'attributo EntryPoint identifica la classe qualificata dello spazio dei nomi che implementa il servizio, che verrà implementato successivamente.

L'attributo SupportsMultipleInstances indica che ogni volta che il servizio app viene chiamato che deve essere eseguito in un nuovo processo. Questo non è obbligatorio, ma è disponibile se si ha bisogno di questa funzionalità e si ha come destinazione 10.0.15063 SDK (Windows 10 Creators Update) o versione successiva. Deve anche essere preceduto dallo spazio dei nomi uap4.

Creare il servizio app

  1. Un servizio app può essere implementato come attività in background. Ciò consente a un'applicazione in primo piano di richiamare un servizio app in un'altra applicazione. Per creare un servizio app come attività in background, aggiungere un nuovo progetto di componente Windows Runtime alla soluzione (File > Aggiungi > Nuovo Progetto) denominato MyAppService. Nella finestra di dialogo Aggiungi nuovo progetto selezionare Installato > Componente Windows Runtime di Visual C# > (Windows universal).

  2. Nel progetto AppServiceProvider aggiungere un riferimento da progetto a progetto al nuovo progetto MyAppService (in Solution Explorer, fare clic con il tasto destro sul progetto AppServiceProvider>Aggiungere>Riferimento>Progetti>Soluzione, selezionare MyAppService>OK). Questo passaggio è fondamentale perché se non si aggiunge il riferimento, il servizio app non si connetterà in fase di esecuzione.

  3. Nel progetto MyAppService aggiungere le istruzioni using seguenti all'inizio di Class1.cs:

    using Windows.ApplicationModel.AppService;
    using Windows.ApplicationModel.Background;
    using Windows.Foundation.Collections;
    
  4. Rinominare Class1.cs in Inventory.cs e sostituire il codice stub per Class1 con una nuova classe di attività in background denominata 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();
            }
        }
    }
    

    Questa classe è la posizione in cui il servizio app eseguirà il proprio lavoro.

    L'esecuzione viene chiamata quando viene creata l'attività in background. Poiché le attività in background vengono terminate dopo il completamento dell'esecuzione, il codice emette un differimento in modo che l'attività in background rimanga aggiornata per gestire le richieste. Un servizio app implementato come attività in background rimarrà attivo per circa 30 secondi dopo che riceve una chiamata, a meno che non venga chiamato di nuovo entro tale intervallo di tempo o che venga estratto un rinvio. Se il servizio app viene implementato nello stesso processo del chiamante, la durata del servizio app è associata alla durata del chiamante.

    La durata del servizio app dipende dal chiamante:

    • Se il chiamante è in primo piano, la durata del servizio app corrisponde al chiamante.
    • Se il chiamante è in background, il servizio app richiede 30 secondi per l'esecuzione. L'esecuzione di un differitore fornisce un'ulteriore volta 5 secondi.

    OnTaskCanceled viene chiamato quando l'attività viene annullata. L'attività viene annullata quando l'app client elimina AppServiceConnection, l'app client viene sospesa, il sistema operativo viene arrestato o viene sospeso oppure il sistema operativo esaurisce le risorse per eseguire l'attività.

Scrivere il codice per il servizio app

OnRequestReceived è la posizione in cui va il codice per il servizio app. Sostituire lo stub OnRequestReceived in Inventory.cs di MyAppService con il codice di questo esempio. Questo codice ottiene un indice per un articolo di inventario e lo passa, insieme a una stringa di comando, al servizio per recuperare il nome e il prezzo dell'articolo di inventario specificato. Per i progetti personalizzati, aggiungere il codice di gestione degli errori.

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();
    }
}

Si noti che OnRequestReceived è asincrono perché in questo esempio viene eseguita una chiamata al metodo disponibile a SendResponseAsync.

Viene eseguito un rinvio in modo che il servizio possa usare metodi asincroni nel gestore OnRequestReceived. Garantisce che la chiamata a OnRequestReceived non venga completata fino a quando non viene eseguita l'elaborazione del messaggio. SendResponseAsync invia il risultato al chiamante. SendResponseAsync non segnala il completamento della chiamata. È il completamento del differimento che segnala a SendMessageAsync che OnRequestReceived è stato completato. La chiamata a SendResponseAsync viene sottoposta a wrapping in un blocco try/finally perché è necessario completare il differimento anche se SendResponseAsync genera un'eccezione.

I servizi app usano oggetti ValueSet per scambiare informazioni. Le dimensioni dei dati che è possibile passare sono limitate solo dalle risorse di sistema. Non sono disponibili chiavi predefinite da usare nel ValueSet. È necessario determinare quali valori chiave si useranno per definire il protocollo per il servizio app. Il chiamante deve essere scritto tenendo presente tale protocollo. In questo esempio è stata scelta una chiave denominata Command con un valore che indica se si vuole che il servizio app fornisca il nome dell'articolo di inventario o il relativo prezzo. L'indice del nome dell'inventario viene archiviato sotto la chiave ID. Il valore restituito viene archiviato nella chiave Result.

Un'enumerazione AppServiceClosedStatus viene restituita al chiamante per indicare se la chiamata al servizio app ha avuto esito positivo o negativo. Un esempio di come la chiamata al servizio app potrebbe non riuscire è se il sistema operativo interrompe l'endpoint del servizio perché le risorse sono state superate. È possibile restituire informazioni aggiuntive sull'errore tramite ValueSet. In questo esempio viene usata una chiave denominata Status per restituire informazioni più dettagliate sull'errore al chiamante.

La chiamata a SendResponseAsync restituisce ValueSet al chiamante.

Distribuire l'app del servizio e ottenere il nome della famiglia di pacchetti

Il provider del servizio app deve essere distribuito prima di poterlo chiamare da un client. È possibile distribuirla selezionando Compila > soluzione di distribuzione in Visual Studio.

È necessario anche il nome della famiglia di pacchetti del provider di servizi app per chiamarlo. È possibile ottenerlo aprendo il file Package.appxmanifest del progetto AppServiceProvider nella visualizzazione della finestra di progettazione (fare doppio clic su di esso nel Esplora soluzioni). Selezionare la scheda Creazione pacchetti, copiare il valore accanto a Nome famiglia pacchetto e incollarlo in un punto come Blocco note per il momento.

Scrivere un client per chiamare il servizio app

  1. Aggiungere un nuovo progetto di app Windows Universal vuoto alla soluzione con File > Aggiungi > Nuovo progetto. Nella finestra di dialogo Aggiungi nuovo progetto selezionare App vuota Visual C# > installata > (Windows Universal) e denominarla ClientApp.

  2. Nel progetto ClientApp aggiungere l'istruzione seguente usando all'inizio di MainPage.xaml.cs:

    using Windows.ApplicationModel.AppService;
    
  3. Aggiungere una casella di testo denominata textBox e un pulsante a MainPage.xaml.

  4. Aggiungere un gestore di clic del pulsante per il pulsante denominato button_Click e aggiungere la parola chiave asincrona alla firma del gestore del pulsante.

  5. Sostituire lo stub del gestore di clic del pulsante con il codice seguente. Assicurarsi di includere la dichiarazione di campo 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;
    }
    

    Sostituire il nome della famiglia di pacchetti nella riga this.inventoryService.PackageFamilyName = "Replace with the package family name"; con il nome della famiglia di pacchetti del progetto AppServiceProvider ottenuto in precedenza in Distribuire l'app del servizio e ottenere il nome della famiglia di pacchetti.

    Nota

    Assicurarsi di incollare il valore letterale stringa anziché inserirlo in una variabile. Non funzionerà se si usa una variabile.

    Il codice stabilisce prima una connessione con il servizio app. La connessione rimarrà aperta fino a quando non si elimina this.inventoryService. Il nome del servizio app deve corrispondere all'attributo AppService dell'elemento Name aggiunto al file Package.appxmanifest del progetto AppServiceProvider. In questo esempio si tratta di <uap3:AppService Name="com.microsoft.inventory"/>.

    Viene creato un oggetto ValueSet denominato message per specificare il comando da inviare al servizio app. Il servizio app di esempio prevede un comando per indicare quali di due azioni eseguire. Ottenere l'indice dalla casella di testo nell'app client e quindi chiamare il servizio con il comando Item per ottenere la descrizione dell'elemento. Eseguire quindi la chiamata con il comando Price per ottenere il prezzo dell'elemento. Il testo del pulsante è impostato sul risultato.

    Poiché AppServiceResponseStatus indica solo se il sistema operativo è stato in grado di connettere la chiamata al servizio app, viene controllata la Status chiave in ValueSet ricevuto dal servizio app per assicurarsi che sia stata in grado di soddisfare la richiesta.

  6. Impostare il progetto ClientApp come progetto di avvio (fare clic con il pulsante destro del mouse in Esplora soluzioni>Imposta come progetto di avvio) ed eseguire la soluzione. Immettere il numero 1 nella casella di testo e fare clic sul pulsante. Si dovrebbe ottenere "Sedia : Prezzo = 88,99" dal servizio.

    sample app displaying chair price=88.99

Se la chiamata al servizio app non riesce, controllare quanto segue nel progetto ClientApp:

  1. Verificare che il nome della famiglia di pacchetti assegnato alla connessione al servizio di inventario corrisponda al nome della famiglia di pacchetti dell'app AppServiceProvider. Vedere la riga in button_Click con this.inventoryService.PackageFamilyName = "...";.
  2. In button_Click verificare che il nome del servizio app assegnato alla connessione al servizio inventario corrisponda al nome del servizio app nel file Package.appxmanifest di AppServiceProvider. (Vedere: this.inventoryService.AppServiceName = "com.microsoft.inventory";.
  3. Assicurarsi che l'app AppServiceProvider sia stata distribuita. (In Solution Explorer, fare clic con il tasto destro sulla soluzione e selezionare Deploy Solution).

Eseguire il debug del servizio app

  1. Assicurarsi che la soluzione venga distribuita prima del debug perché l'app del provider di servizi app deve essere distribuita prima di poter chiamare il servizio. (In Visual Studio, compilare > Deploy Solution).
  2. In Esplora soluzioni fare clic con il tasto destro del mouse sul progetto AppServiceProvider e scegli Proprietà. Nella scheda Debug modificare l'azione Avvia in Non avviare, ma eseguire il debug del codice all'avvio. Si noti che, se si usa C++ per implementare il provider di servizi app, dalla scheda Debug si cambia Avvia applicazione in No).
  3. Nel progetto MyAppService, nel file Inventory.cs, impostare breakpoint in OnRequestReceived.
  4. Impostare il progetto AppServiceProvider come progetto di avvio e premere F5.
  5. Avviare ClientApp dal menu Start (non da Visual Studio).
  6. Immettere il numero 1 nella casella di testo e premere il pulsante. Il debugger si arresterà nella chiamata al servizio app sul punto di interruzione nel servizio app.

Eseguire il debug del client

  1. Seguire le istruzioni nel passaggio precedente per eseguire il debug del client che chiama il servizio app.
  2. Avviare ClientApp dal menu Start.
  3. Collegare il debugger al processo di ClientApp.exe (non al processo di ApplicationFrameHost.exe). (In Visual Studio fare clic su seleziona Debug> Connetti a processo...).
  4. Nel progetto ClientApp impostare un punto di interruzione in button_Click.
  5. I punti di interruzione nel client e nel servizio app verranno ora raggiunti quando si immette il numero 1 nella casella di testo clientApp e si fa clic sul pulsante.

Risoluzione dei problemi relativi al Servizio app generico

Se si verifica uno stato AppUnavailable dopo aver tentato di connettersi a un servizio app, verificare quanto segue:

  • Assicurarsi che il progetto del provider del servizio app e il progetto del servizio app siano distribuiti. Entrambi devono essere distribuiti prima di eseguire il client perché in caso contrario il client non avrà nulla a cui connettersi. È possibile eseguire la distribuzione da Visual Studio usando Compila>Deploy Solution.
  • In Esplora soluzioni assicurarsi che il progetto del provider di servizi app abbia un riferimento da progetto a progetto al progetto che implementa il servizio app.
  • Verificare che la <Extensions> voce e i relativi elementi figlio siano stati aggiunti al file Package.appxmanifest appartenente al progetto del provider del servizio app come specificato in precedenza in Aggiungere un'estensione del servizio app a Package.appxmanifest.
  • Assicurarsi che la stringa AppServiceConnection.AppServiceName nel client che chiama il provider del servizio app corrisponde a quella <uap3:AppService Name="..." /> specificata nel file Package.appxmanifest del progetto del provider del servizio app.
  • Assicurarsi che AppServiceConnection.PackageFamilyName corrisponde al nome della famiglia di pacchetti del componente del provider del servizio app come specificato in precedenza in Aggiungere un'estensione del servizio app a Package.appxmanifest
  • Per i servizi app out-of-process, ad esempio quello di questo esempio, verificare che l'oggetto EntryPoint specificato nell'elemento <uap:Extension ...> del file Package.appxmanifest del progetto del provider di servizi app corrisponda allo spazio dei nomi e al nome della classe pubblica che implementa IBackgroundTask nel progetto del servizio app.

Risolvere i problemi di esecuzione del debug

Se il debugger non si arresta in corrispondenza dei punti di interruzione nei progetti del provider di servizi app o del servizio app, verificare quanto segue:

  • Assicurarsi che il progetto del provider del servizio app e il progetto del servizio app siano distribuiti. Entrambi devono essere distribuiti prima di eseguire il client. È possibile eseguire la loro distribuzione da Visual Studio usando Compila>Deploy Solution.
  • Assicurarsi che il progetto di cui si vuole eseguire il debug sia impostato come progetto di avvio e che le proprietà di debug per tale progetto siano impostate per non eseguire il progetto quando viene premuto F5. Fare clic con il tasto destro del mouse sul progetto, quindi fare clic su Proprietà e poi su Debug (o Debugging in C++). In C# modificare l'azione Avvia in Non avviare, ma eseguire il debug del codice all'avvio. In C++ impostare Avvia applicazione su No.

Osservazioni:

Questo esempio fornisce un'introduzione alla creazione di un servizio app che viene eseguito come attività in background e alla chiamata da un'altra app. Le cose chiave da notare sono:

  • Creare un'attività in background per ospitare il servizio app.
  • Aggiungere l'estensione windows.appService al file Package.appxmanifest del provider del servizio app.
  • Ottenere il nome della famiglia di pacchetti del provider del servizio app in modo che sia possibile connettersi all'app client.
  • Aggiungere un riferimento da progetto a progetto dal progetto del provider del servizio app al progetto del servizio app.
  • Usare Windows.ApplicationModel.AppService.AppServiceConnection per chiamare il servizio.

Codice completo per 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();
            }
        }
    }
}