Erstellen und Verwenden eines App-Diensts

Wichtig

Die Codeauflistungen in diesem Thema sind nur C#. Eine App Service-Beispiel-App in C++/WinRT sowie C# finden Sie unter App Service-Beispiel-App.

App-Dienste sind UWP-Apps, die Dienste für andere UWP-Apps bereitstellen. Sie entsprechen Webdiensten auf einem Gerät. Ein App-Dienst wird als Hintergrundaufgabe in der Host-App ausgeführt und kann seine Dienste auch anderen Apps bereitstellen. Beispielsweise kann der Barcode-Scanner eines App-Dienstes auch anderen Apps nützlich sein. Oder vielleicht verfügt eine Enterprise-Suite von Apps über einen gemeinsamen App-Dienst zur Rechtschreibprüfung, der für die anderen Apps in der Suite verfügbar ist. Mit App-Diensten können Sie Dienste ohne Benutzeroberfläche erstellen, die Apps auf demselben Gerät und ab Windows 10, Version 1607, auch auf Remotegeräten aufrufen können.

Ab Windows 10, Version 1607, können Sie App-Dienste erstellen, die im gleichen Prozess wie die Vordergrund-App ausgeführt werden. Dieser Artikel konzentriert sich auf das Erstellen und Verwenden eines App-Diensts, der in einem separaten Hintergrundprozess ausgeführt wird. Weitere Informationen zum Ausführen eines App-Diensts im selben Prozess wie die Host-App finden Sie unter Konvertieren eines App-Diensts in denselben Prozess wie der Anbieter.

Erstellen eines neuen App-Dienstanbieterprojekts

In dieser Anleitung erstellen wir der Einfachheit halber alles in einer Projektmappe.

  1. Erstellen Sie in Visual Studio 2015 oder höher ein neues UWP-App-Projekt, und nennen Sie es AppServiceProvider.

    1. Wählen Sie Datei > Neues > Projekt... aus...
    2. Wählen Sie im Dialogfeld Neues Projekt erstellen die Option Leere App (Universelles Windows) C# aus. Dies ist die App, die den App-Dienst für andere UWP-Apps verfügbar macht.
    3. Klicken Sie auf Weiter, geben Sie dem Projekt den Namen AppServiceProvider, wählen Sie einen Speicherort dafür aus, und klicken Sie dann auf Erstellen.
  2. Wenn Sie aufgefordert werden, eine Ziel- und Mindestversion für das Projekt auszuwählen, wählen Sie mindestens 10.0.14393 aus. Wenn Sie das neue Attribut SupportsMultipleInstances verwenden möchten, müssen Sie Visual Studio 2017 oder Visual Studio 2019 und ziel 10.0.15063 (Windows 10 Creators Update) oder höher verwenden.

Hinzufügen einer App Service-Erweiterung zu Package.appxmanifest

Öffnen Sie im Projekt AppServiceProvider die Datei Package.appxmanifest in einem Text-Editor:

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste darauf.
  2. Wählen Sie Öffnen mit aus.
  3. Wählen Sie XML (Text)-Editor aus.

Fügen Sie dem -Element die <Application> folgende AppService Erweiterung hinzu. Durch dieses Beispiel wird der com.microsoft.inventory-Dienst angekündigt, und die App wird als App-Dienstanbieter identifiziert. Der eigentliche Dienst wird als Hintergrundaufgabe implementiert. Das App Service-Projekt macht den Dienst für andere Apps verfügbar. Wir empfehlen, einen umgekehrten Domänennamen für den Dienstnamen zu verwenden.

Beachten Sie, dass das xmlns:uap4 Namespacepräfix und das uap4:SupportsMultipleInstances Attribut nur gültig sind, wenn Sie Windows SDK Version 10.0.15063 oder höher als Ziel verwenden. Sie können sie sicher entfernen, wenn Sie auf ältere SDK-Versionen abzielen.

Hinweis

Eine App Service-Beispiel-App in C++/WinRT sowie C# finden Sie unter App Service-Beispiel-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>

Das Category -Attribut identifiziert diese Anwendung als App-Dienstanbieter.

Das EntryPoint Attribut identifiziert die namespacequalifizierte Klasse, die den Dienst implementiert, den wir als Nächstes implementieren.

Das SupportsMultipleInstances Attribut gibt an, dass der App-Dienst bei jedem Aufruf in einem neuen Prozess ausgeführt werden soll. Dies ist nicht erforderlich, steht Ihnen aber zur Verfügung, wenn Sie diese Funktionalität benötigen und auf das SDK 10.0.15063 (Windows 10 Creators Update) oder höher abzielen. Sie sollte auch vom uap4 Namespace vorab bereitgestellt werden.

Erstellen des App-Diensts

  1. Ein App-Dienst kann als Hintergrundaufgabe implementiert werden. Dadurch kann eine Vordergrundanwendung einen App-Dienst in einer anderen Anwendung aufrufen. Um einen App Service als Hintergrundaufgabe zu erstellen, fügen Sie der Projektmappe (File > Add > New Project) ein neues Windows-Runtime-Komponentenprojekt mit dem Namen MyAppService hinzu. Wählen Sie im Dialogfeld Neues Projekt hinzufügen die Option Installierte > Visual C#- > Windows-Runtime-Komponente (Universelles Windows) aus.

  2. Fügen Sie im AppServiceProvider-Projekt einen Projekt-zu-Projekt-Verweis zum neuen MyAppService-Projekt hinzu (klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt> AppServiceProviderReferenzprojekte>>hinzufügen>, und wählen Sie MyAppService>OK aus. Dieser Schritt ist wichtig, da der App-Dienst zur Laufzeit keine Verbindung herstellt, wenn Sie den Verweis nicht hinzufügen.

  3. Fügen Sie im Projekt MyAppService die folgenden using-Anweisungen am Anfang von Class1.cs hinzu:

    using Windows.ApplicationModel.AppService;
    using Windows.ApplicationModel.Background;
    using Windows.Foundation.Collections;
    
  4. Benennen Sie Class1.cs in Inventory.cs um, und ersetzen Sie den Stubcode für Class1 durch eine neue Hintergrundaufgabenklasse namens 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();
            }
        }
    }
    

    In dieser Klasse wird der App-Dienst ausgeführt.

    Ausführen wird aufgerufen, wenn die Hintergrundaufgabe erstellt wird. Da Hintergrundaufgaben nach Abschluss der Ausführung beendet werden, nimmt der Code eine Verzögerung aus, sodass die Hintergrundaufgabe zum Verarbeiten von Anforderungen auf dem neuesten Stand bleibt. Ein App-Dienst, der als Hintergrundaufgabe implementiert ist, bleibt etwa 30 Sekunden lang am Leben, nachdem er einen Anruf empfangen hat, es sei denn, er wird innerhalb dieses Zeitfensters erneut aufgerufen oder eine Verzögerung wird gelöscht. Wenn der App-Dienst im selben Prozess wie der Aufrufer implementiert wird, ist die Lebensdauer des App-Diensts an die Lebensdauer des Aufrufers gebunden.

    Die Lebensdauer des App-Diensts hängt vom Aufrufer ab:

    • Wenn sich der Aufrufer im Vordergrund befindet, ist die Lebensdauer des App-Diensts identisch mit dem Aufrufer.
    • Wenn sich der Aufrufer im Hintergrund befindet, erhält der App-Dienst 30 Sekunden für die Ausführung. Das Herausnehmen einer Verzögerung bietet eine zusätzliche zeit von 5 Sekunden.

    OnTaskCanceled wird aufgerufen, wenn die Aufgabe abgebrochen wird. Die Aufgabe wird abgebrochen, wenn die Client-App die AppServiceConnection veräußert, die Client-App angehalten wird, das Betriebssystem heruntergefahren wird oder sich im Ruhezustand befindet oder das Betriebssystem die Ressourcen zum Ausführen der Aufgabe ausgeht.

Schreiben des Codes für den App-Dienst

OnRequestReceived ist der Ort, an dem sich der Code für den App-Dienst befindet. Ersetzen Sie den Stub OnRequestReceived in "Inventory.cs" von MyAppService durch den Code aus diesem Beispiel. Dieser Code ruft einen Index für ein Bestandselement ab und übergibt ihn zusammen mit einer Befehlszeichenfolge an den Dienst, um den Namen und Preis des angegebenen Bestandselements abzurufen. Fügen Sie für Ihre eigenen Projekte Fehlerbehandlungscode hinzu.

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

Beachten Sie, dass OnRequestReceivedasynchron ist, da wir in diesem Beispiel einen wartenden Methodenaufruf für SendResponseAsync vornehmen.

Es wird eine Verzögerung vorgenommen, damit der Dienst asynchrone Methoden im OnRequestReceived-Handler verwenden kann. Dadurch wird sichergestellt, dass der Aufruf von OnRequestReceived erst abgeschlossen ist, wenn die Verarbeitung der Nachricht abgeschlossen ist. SendResponseAsync sendet das Ergebnis an den Aufrufer. SendResponseAsync signalisiert nicht den Abschluss des Aufrufs. Es ist der Abschluss der Verzögerung, der SendMessageAsync signalisiert, dass OnRequestReceived abgeschlossen wurde. Der Aufruf von SendResponseAsync wird in einen Try/Finally-Block eingeschlossen, da Sie die Zurückstellung auch dann abschließen müssen, wenn SendResponseAsync eine Ausnahme auslöst.

App Services verwenden ValueSet-Objekte , um Informationen auszutauschen. Die Größe der Daten, die übergeben werden können, ist nur durch die Systemressourcen begrenzt. Es gibt keine vordefinierten Schlüssel zur Verwendung in Ihrem ValueSet. Sie müssen bestimmen, welche Schlüsselwerte Sie zum Definieren des Protokolls für Ihren App-Dienst verwenden. Dieses Protokoll muss beim Schreiben des Aufrufers berücksichtigt werden. In diesem Beispiel haben wir einen Schlüssel mit dem Namen ausgewählt Command , der über einen Wert verfügt, der angibt, ob der App-Dienst den Namen des Bestandselements oder dessen Preis angeben soll. Der Index des Bestandsnamens wird unter dem ID Schlüssel gespeichert. Der Rückgabewert wird unter dem Result Schlüssel gespeichert.

An den Aufrufer wird eine AppServiceClosedStatus-Enumeration zurückgegeben, um anzugeben, ob der Aufruf des App-Diensts erfolgreich war. Ein Beispiel dafür, wie der Aufruf des App-Diensts fehlschlagen kann, ist, wenn das Betriebssystem den Dienstendpunkt abbricht, weil seine Ressourcen überschritten wurden. Sie können über ValueSet zusätzliche Fehlerinformationen zurückgeben. In diesem Beispiel verwenden wir einen Schlüssel namens Status , um ausführlichere Fehlerinformationen an den Aufrufer zurückzugeben.

Der Aufruf von SendResponseAsync gibt ValueSet an den Aufrufer zurück.

Bereitstellen der Dienstanbieter-App und Abrufen des Paketfamiliennamens

Der App-Dienstanbieter muss bereitgestellt werden, bevor Sie ihn von einem Client aufrufen können. Sie können es bereitstellen, indem Sie Projektmappe in Visual Studio erstellen > auswählen.

Sie benötigen auch den Paketfamiliennamen des App-Dienstanbieters, um ihn aufrufen zu können. Sie können es abrufen, indem Sie die Datei Package.appxmanifest des AppServiceProvider-Projekts in der Designeransicht öffnen (doppelklicken Sie darauf im Projektmappen-Explorer). Wählen Sie die Registerkarte Verpackung aus, kopieren Sie den Wert neben Paketfamilienname, und fügen Sie ihn jetzt wie Editor ein.

Schreiben eines Clients zum Aufrufen des App-Diensts

  1. Fügen Sie der Projektmappe mit "Neues Projekt hinzufügen>" ein neues leeres Universelles Windows-App-Projekt >hinzu. Wählen Sie im Dialogfeld Neues Projekt hinzufügen die Option Installierte > leere Visual C#- > App (Universelles Windows) aus, und nennen Sie es ClientApp.

  2. Fügen Sie im ClientApp-Projekt die folgende using-Anweisung am Anfang von MainPage.xaml.cs hinzu:

    using Windows.ApplicationModel.AppService;
    
  3. Fügen Sie mainPage.xaml ein Textfeld namens textBox und eine Schaltfläche hinzu.

  4. Fügen Sie einen Schaltflächenklickhandler für die Schaltfläche namens button_Click hinzu, und fügen Sie das Schlüsselwort asynchron zur Signatur des Schaltflächenhandlers hinzu.

  5. Ersetzen Sie den Stub des Klickhandlers für die Schaltfläche durch den folgenden Code. Vergessen Sie nicht die inventoryService-Felddeklaration.

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

    Ersetzen Sie den Paketfamiliennamen in der Zeile this.inventoryService.PackageFamilyName = "Replace with the package family name"; durch den Paketfamiliennamen des AppServiceProvider-Projekts , den Sie oben unter Bereitstellen der Dienst-App und Abrufen des Paketfamiliennamens abgerufen haben.

    Hinweis

    Stellen Sie sicher, dass Sie das Zeichenfolgenliteral einfügen, anstatt es in einer Variablen zu platzieren. Dies funktioniert nicht, wenn Sie eine Variable verwenden.

    Der Code richtet zunächst eine Verbindung mit dem App-Dienst ein. Die Verbindung bleibt geöffnet, bis Sie verwerfen this.inventoryService. Der App Service-Name muss mit dem AppService Attribut des Name Elements übereinstimmen, das Sie der Package.appxmanifest-Datei des AppServiceProvider-Projekts hinzugefügt haben. In diesem Beispiel lautet er <uap3:AppService Name="com.microsoft.inventory"/>.

    Ein ValueSet mit dem Namen message wird erstellt, um den Befehl anzugeben, den wir an den App-Dienst senden möchten. Der Beispiel-App-Dienst erwartet einen Befehl, der angibt, welche der beiden Aktionen ausgeführt werden soll. Wir rufen den Index aus dem Textfeld in der Client-App ab und rufen dann den Dienst mit dem Item Befehl auf, um die Beschreibung des Elements abzurufen. Anschließend führen wir den Aufruf mit dem Price Befehl aus, um den Preis des Artikels zu erhalten. Der Text der Schaltfläche wird auf das Ergebnis festgelegt.

    Da AppServiceResponseStatus nur angibt, ob das Betriebssystem den Aufruf mit dem App-Dienst verbinden konnte, überprüfen wir den Status Schlüssel im ValueSet , das wir vom App-Dienst erhalten, um sicherzustellen, dass es die Anforderung erfüllen konnte.

  6. Legen Sie das ClientApp-Projekt als Startprojekt fest (klicken Sie im Projektmappen-Explorer>Als Startprojekt festlegen) mit der rechten Maustaste darauf, und führen Sie die Projektmappe aus. Geben Sie 1 in das Textfeld ein, und klicken Sie auf die Schaltfläche. Der Dienst sollte „Stuhl: Preis = 88,99“ zurückgeben.

    Beispiel-App, die Stuhlpreis = 88,99 anzeigt

Wenn der App Service-Aufruf fehlschlägt, überprüfen Sie Folgendes im ClientApp-Projekt :

  1. Stellen Sie sicher, dass der Paketfamilienname, der der Inventurdienstverbindung zugewiesen ist, mit dem Paketfamiliennamen der AppServiceProvider-App übereinstimmt. Weitere Informationen finden Sie in der Zeile in button_Click mit this.inventoryService.PackageFamilyName = "...";.
  2. Überprüfen Sie in button_Click, ob der App Service-Name, der der Inventurdienstverbindung zugewiesen ist, mit dem App-Dienstnamen in der Datei Package.appxmanifest des AppServiceProviders übereinstimmt. Weitere Informationen finden Sie unter this.inventoryService.AppServiceName = "com.microsoft.inventory";.
  3. Stellen Sie sicher, dass die AppServiceProvider-App bereitgestellt wurde. (Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Lösung, und wählen Sie Lösung bereitstellen aus.

Debuggen des App-Diensts

  1. Stellen Sie sicher, dass die Lösung vor dem Debuggen bereitgestellt wird, da die App-Dienstanbieter-App bereitgestellt werden muss, bevor der Dienst aufgerufen werden kann. (Klicken Sie in Visual Studio auf Erstellen > Projektmappe bereitstellen.)
  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt AppServiceProvider, und wählen Sie Eigenschaften aus. Ändern Sie auf der Registerkarte Debuggen die Startaktion in Eigenen Code zunächst nicht starten, sondern debuggen. (Hinweis: Wenn Sie C++ zum Implementieren Ihres App-Dienstanbieters verwendet haben, würden Sie auf der Registerkarte DebuggenAnwendung starten in Nein ändern.
  3. Legen Sie im Projekt MyAppService in der Datei Inventory.cs einen Haltepunkt in OnRequestReceived fest.
  4. Legen Sie das AppServiceProvider-Projekt als Startprojekt fest, und drücken Sie F5.
  5. Starten Sie ClientApp über das Startmenü (nicht über Visual Studio).
  6. Geben Sie 1 in das Textfeld ein, und klicken Sie auf die Schaltfläche. Der Debugger stoppt im App-Dienstaufruf am Haltepunkt in Ihrem App-Dienst.

Debuggen des Clients

  1. Befolgen Sie die Anweisungen im vorherigen Schritt, um den Client zu debuggen, der den App-Dienst aufruft.
  2. Starten Sie ClientApp über das Startmenü.
  3. Fügen Sie den Debugger an den ClientApp.exe Prozess an (nicht an den ApplicationFrameHost.exe Prozess). (Klicken Sie in Visual Studio auf Debuggen > An den Prozess anhängen.)
  4. Legen Sie im ClientApp-Projekt einen Haltepunkt in button_Click fest.
  5. Die Haltepunkte sowohl im Client als auch im App-Dienst werden nun erreicht, wenn Sie die Zahl 1 in das Textfeld von ClientApp eingeben und auf die Schaltfläche klicken.

Allgemeine App Service-Problembehandlung

Wenn nach dem Versuch, eine Verbindung mit einem App Service herzustellen, der Status AppUnavailable auftritt, überprüfen Sie Folgendes:

  • Stellen Sie sicher, dass das App-Dienstanbieterprojekt und das App Service-Projekt bereitgestellt sind. Beide müssen vor dem Ausführen des Clients bereitgestellt werden, da der Client andernfalls keine Verbindung herstellen kann. Sie können die Bereitstellung über Visual Studio mithilfe von Projektmappe>erstellen.
  • Stellen Sie im Projektmappen-Explorer sicher, dass Ihr App-Dienstanbieterprojekt über einen Projekt-zu-Projekt-Verweis auf das Projekt verfügt, das den App-Dienst implementiert.
  • Vergewissern Sie sich, dass der <Extensions> Eintrag und seine untergeordneten Elemente der Datei Package.appxmanifest hinzugefügt wurden, die zum App-Dienstanbieterprojekt gehört, wie oben unter Hinzufügen einer App Service-Erweiterung zu Package.appxmanifest angegeben.
  • Stellen Sie sicher, dass die AppServiceConnection.AppServiceName-Zeichenfolge in Ihrem Client, der den App-Dienstanbieter aufruft, mit dem <uap3:AppService Name="..." /> in der Datei Package.appxmanifest des App-Dienstanbieterprojekts übereinstimmt.
  • Stellen Sie sicher, dass AppServiceConnection.PackageFamilyName mit dem Paketfamiliennamen der App-Dienstanbieterkomponente übereinstimmt, wie oben unter Hinzufügen einer App-Diensterweiterung zu Package.appxmanifest angegeben.
  • Überprüfen Sie für out-of-proc-App-Dienste wie die in diesem Beispiel, ob der EntryPoint im <uap:Extension ...> Element der Package.appxmanifest-Datei Ihres App-Dienstanbieterprojekts angegebene mit dem Namespace und dem Klassennamen der öffentlichen Klasse übereinstimmt, die IBackgroundTask in Ihrem App Service-Projekt implementiert.

Behandeln von Problemen beim Debuggen

Wenn der Debugger nicht an Haltepunkten in Ihrem App-Dienstanbieter oder in App Service-Projekten anhält, überprüfen Sie Folgendes:

  • Stellen Sie sicher, dass das App-Dienstanbieterprojekt und das App Service-Projekt bereitgestellt sind. Beide müssen bereitgestellt werden, bevor der Client ausgeführt wird. Sie können sie über Visual Studio bereitstellen, indem Sie projektmappe erstellen>.
  • Stellen Sie sicher, dass das Projekt, das Sie debuggen möchten, als Startprojekt festgelegt ist und dass die Debugeigenschaften für dieses Projekt so festgelegt sind, dass das Projekt nicht ausgeführt wird, wenn F5 gedrückt wird. Klicken Sie mit der rechten Maustaste auf das Projekt, klicken Sie dann auf Eigenschaften, und klicken Sie dann auf Debuggen (oder Debuggen in C++). Ändern Sie in C# die Startaktion in Nicht starten, sondern debuggen Sie den Code, wenn er gestartet wird. Legen Sie in C++ die Einstellung Anwendung starten auf Nein fest.

Bemerkungen

Dieses Beispiel bietet eine Einführung in das Erstellen eines App-Diensts, der als Hintergrundaufgabe ausgeführt und von einer anderen App aufgerufen wird. Die wichtigsten Punkte, die sie beachten müssen, sind:

  • Erstellen Sie eine Hintergrundaufgabe zum Hosten des App-Diensts.
  • Fügen Sie die windows.appService Erweiterung der Datei Package.appxmanifest des App-Dienstanbieters hinzu.
  • Rufen Sie den Paketfamiliennamen des App-Dienstanbieters ab, damit wir über die Client-App eine Verbindung mit diesem Herstellen herstellen können.
  • Fügen Sie dem App Service-Projekt einen Projekt-zu-Projekt-Verweis aus dem App Service-Anbieterprojekt hinzu.
  • Verwenden Sie Windows.ApplicationModel.AppService.AppServiceConnection , um den Dienst aufzurufen.

Vollständiger Code für „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();
            }
        }
    }
}