Crear y usar un servicio de aplicacionesCreate and consume an app service

Los servicios de aplicaciones son aplicaciones para UWP que proporcionan servicios a otras aplicaciones de UWP.App services are UWP apps that provide services to other UWP apps. Son análogos a los servicios Web, en un dispositivo.They are analogous to web services, on a device. Una aplicación de App Service se ejecuta como una tarea en segundo plano en la aplicación host y puede proporcionar su servicio a otras aplicaciones.An app service runs as a background task in the host app and can provide its service to other apps. Por ejemplo, un servicio de aplicaciones podría proporcionar un servicio de análisis de código de barras que otras aplicaciones podrían usar.For example, an app service might provide a bar code scanner service that other apps could use. O quizás un conjunto de aplicaciones de empresa tiene un servicio de aplicaciones de revisión ortográfica común que está disponible para las demás aplicaciones del conjunto.Or perhaps an Enterprise suite of apps has a common spell checking app service that is available to the other apps in the suite. App Services le permite crear servicios sin interfaz de usuario que las aplicaciones pueden llamar en el mismo dispositivo y a partir de Windows 10, versión 1607, en dispositivos remotos.App services let you create UI-less services that apps can call on the same device, and starting with Windows 10, version 1607, on remote devices.

A partir de Windows 10, versión 1607, puedes crear servicios de aplicación que se ejecutan en el mismo proceso que la aplicación host.Starting in Windows 10, version 1607, you can create app services that run in the same process as the host app. Este artículo se centra en la creación y el consumo de una aplicación de App Service que se ejecuta en un proceso en segundo plano independiente.This article focuses on creating and consuming an app service that runs in a separate background process. Consulte conversión de un servicio de aplicaciones para que se ejecute en el mismo proceso que su aplicación host para obtener más detalles sobre cómo ejecutar un servicio de aplicaciones en el mismo proceso que el proveedor.See Convert an app service to run in the same process as its host app for more details about running an app service in the same process as the provider.

Para obtener un ejemplo de código de App Service, consulte ejemplos de aplicaciones de plataforma universal de Windows (UWP).For an app service code sample, see Universal Windows Platform (UWP) app samples.

Crear un proyecto nuevo de proveedor de servicios de aplicacionesCreate a new app service provider project

En este procedimiento, lo crearemos todo en una solución para hacerlo más sencillo.In this how-to, we'll create everything in one solution for simplicity.

  1. En Visual Studio 2015 o posterior, cree un nuevo proyecto de aplicación para UWP y asígnele el nombre AppServiceProvider.In Visual Studio 2015 or later, create a new UWP app project and name it AppServiceProvider.

    1. Seleccione el archivo > nuevo proyecto de >...Select File > New > Project...
    2. En el cuadro de diálogo crear un nuevo proyecto , seleccione aplicación vacía (Windows universal) C#.In the Create a new project dialog box, select Blank App (Universal Windows) C#. Se trata de la aplicación que hace que App Service esté disponible para otras aplicaciones de UWP.This will be the app that makes the app service available to other UWP apps.
    3. Haga clic en siguientey, a continuación, asigne al proyecto el nombre AppServiceProvider, elija una ubicación para él y, a continuación, haga clic en crear.Click Next, and then name the project AppServiceProvider, choose a location for it, and then click Create.
  2. Cuando se le pida que seleccione un destino y una versión mínima para el proyecto, seleccione al menos 10.0.14393.When asked to select a Target and Minimum version for the project, select at least 10.0.14393. Si desea usar el nuevo atributo SupportsMultipleInstances , debe usar visual Studio 2017 o visual Studio 2019 y el destino 10.0.15063 (Windows 10 Creators Update) o superior.If you want to use the new SupportsMultipleInstances attribute, you must be using Visual Studio 2017 or Visual Studio 2019, and target 10.0.15063 (Windows 10 Creators Update) or higher.

Agregar una extensión de App Service a package. appxmanifestAdd an app service extension to Package.appxmanifest

En el proyecto AppServiceProvider , abra el archivo Package. appxmanifest en un editor de texto:In the AppServiceProvider project, open the Package.appxmanifest file in a text editor:

  1. Haga clic con el botón secundario en el Explorador de soluciones.Right-click it in the Solution Explorer.
  2. Seleccione abrir con.Select Open With.
  3. Seleccione Editor XML (texto).Select XML (Text) Editor.

Agregue la siguiente AppService extensión dentro del <Application> elemento.Add the following AppService extension inside the <Application> element. Este ejemplo anuncia el servicio com.microsoft.inventory y es lo que identifica a esta aplicación como un proveedor de servicios de aplicaciones.This example advertises the com.microsoft.inventory service and is what identifies this app as an app service provider. El servicio real se implementará como una tarea en segundo plano.The actual service will be implemented as a background task. El proyecto de App Service expone el servicio a otras aplicaciones.The app service project exposes the service to other apps. Se recomienda usar un estilo inverso de nombre de dominio para el nombre del servicio.We recommend using a reverse domain name style for the service name.

Tenga en cuenta que el xmlns:uap4 Prefijo de espacio de nombres y el uap4:SupportsMultipleInstances atributo solo son válidos si tiene como destino Windows SDK versión 10.0.15063 o posterior.Note that the xmlns:uap4 namespace prefix and the uap4:SupportsMultipleInstances attribute are only valid if you are targeting Windows SDK version 10.0.15063 or higher. Puede quitarlos de forma segura si tiene como destino versiones anteriores del SDK.You can safely remove them if you are targeting older SDK versions.

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

El Category atributo identifica esta aplicación como un proveedor de App Service.The Category attribute identifies this application as an app service provider.

El EntryPoint atributo identifica la clase de espacio de nombres calificado que implementa el servicio, que se implementará a continuación.The EntryPoint attribute identifies the namespace qualified class that implements the service, which we'll implement next.

El SupportsMultipleInstances atributo indica que, cada vez que se llama a App Service, debe ejecutarse en un nuevo proceso.The SupportsMultipleInstances attribute indicates that each time the app service is called that it should run in a new process. Esto no es necesario, pero está disponible si necesita esa funcionalidad y tiene como destino el SDK de 10.0.15063 (Windows 10 Creators Update) o superior.This is not required but is available to you if you need that functionality and are targeting the 10.0.15063 SDK (Windows 10 Creators Update) or higher. También debe ir precedido por el espacio de uap4 nombres.It also should be prefaced by the uap4 namespace.

Crear el servicio de aplicacionesCreate the app service

  1. Una aplicación de App Service se puede implementar como una tarea en segundo plano.An app service can be implemented as a background task. Esto permite que una aplicación de primer plano invoque un servicio de aplicaciones en otra aplicación.This enables a foreground application to invoke an app service in another application. Para crear una aplicación de App Service como una tarea en segundo plano, agregue un nuevo Windows Runtime proyecto de componente a la solución (archivo > agregar > nuevo proyecto) llamado MyAppService.To create an app service as a background task, add a new Windows Runtime component project to the solution (File > Add > New Project) named MyAppService. En el cuadro de diálogo Agregar nuevo proyecto , elija instalado > componente de Visual C# > Windows Runtime (Windows universal).In the Add New Project dialog box, choose Installed > Visual C# > Windows Runtime Component (Universal Windows).

  2. En el proyecto appserviceprovider , agregue una referencia de proyecto a proyecto al nuevo proyecto MyAppService (en el Explorador de soluciones, haga clic con el botón derecho en el proyecto AppServiceProvider > solución Agregar > Reference > proyectos > Solutionde referencia, seleccione MyAppService > Aceptar).In the AppServiceProvider project, add a project-to-project reference to the new MyAppService project (in the Solution Explorer, right-click on the AppServiceProvider project > Add > Reference > Projects > Solution, select MyAppService > OK). Este paso es fundamental porque si no agrega la referencia, App Service no se conectará en tiempo de ejecución.This step is critical because if you do not add the reference, the app service won't connect at runtime.

  3. En el proyecto MyAppService , agregue las siguientes instrucciones using a la parte superior de Class1.CS:In the MyAppService project, add the following using statements to the top of Class1.cs:

    using Windows.ApplicationModel.AppService;
    using Windows.ApplicationModel.Background;
    using Windows.Foundation.Collections;
    
  4. Cambie el nombre de Class1.CS a Inventory.CSy reemplace el código auxiliar de Class1 por una nueva clase de tarea en segundo plano denominada Inventory:Rename Class1.cs to Inventory.cs, and replace the stub code for Class1 with a new background task class named 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();
            }
        }
    }
    

    Esta clase es el lugar donde el servicio de aplicaciones hará su trabajo.This class is where the app service will do its work.

    Se llama a Run cuando se crea la tarea en segundo plano.Run is called when the background task is created. Dado que las tareas en segundo plano finalizan una vez completada la ejecución , el código toma un aplazamiento para que la tarea en segundo plano esté a la espera de atender las solicitudes.Because background tasks are terminated after Run completes, the code takes out a deferral so that the background task will stay up to serve requests. Un servicio de aplicaciones que se implementa como una tarea en segundo plano permanecerá activo durante unos 30 segundos después de recibir una llamada a menos que se vuelva a llamar en ese período de tiempo o se extraiga un aplazamiento. Si app Service se implementa en el mismo proceso que el autor de la llamada, la duración de App Service está ligada a la duración del autor de la llamada.An app service that is implemented as a background task will stay alive for about 30 seconds after it receives a call unless it is called again within that time window or a deferral is taken out. If the app service is implemented in the same process as the caller, the lifetime of the app service is tied to the lifetime of the caller.

    La duración de la aplicación de servicio depende del autor de la llamada:The lifetime of the app service depends on the caller:

    • Si el autor de la llamada está en primer plano, la duración de App Service es la misma que la del autor de la llamada.If the caller is in the foreground, the app service lifetime is the same as the caller.
    • Si el autor de la llamada está en segundo plano, el servicio de aplicación obtiene 30 segundos para ejecutarse.If the caller is in the background, the app service gets 30 seconds to run. La toma de un aplazamiento proporciona una vez más una vez 5 segundos.Taking out a deferral provides an additional one time 5 seconds.

    Se llama a OnTaskCanceled cuando se cancela la tarea.OnTaskCanceled is called when the task is canceled. La tarea se cancela cuando la aplicación cliente desecha el AppServiceConnection, se suspende la aplicación cliente, el sistema operativo se apaga o se suspende, o el sistema operativo se queda sin recursos para ejecutar la tarea.The task is canceled when the client app disposes the AppServiceConnection, the client app is suspended, the OS is shut down or sleeps, or the OS runs out of resources to run the task.

Escribir el código para el servicio de aplicacionesWrite the code for the app service

OnRequestReceived es el lugar donde se dirige el código para App Service.OnRequestReceived is where the code for the app service goes. Reemplace el código auxiliar OnRequestReceived en Inventory.CS de MyAppServicepor el código de este ejemplo.Replace the stub OnRequestReceived in MyAppService's Inventory.cs with the code from this example. Este código obtiene un índice para un elemento de inventario y, junto con una cadena de comandos, lo pasa al servicio para recuperar el nombre y el precio del elemento de inventario especificado.This code gets an index for an inventory item and passes it, along with a command string, to the service to retrieve the name and the price of the specified inventory item. Para sus propios proyectos, agregue código de control de errores.For your own projects, add error handling code.

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

Tenga en cuenta que OnRequestReceived es Async porque se realiza una llamada de método que se pueda esperar a SendResponseAsync en este ejemplo.Note that OnRequestReceived is async because we make an awaitable method call to SendResponseAsync in this example.

Se toma un aplazamiento para que el servicio pueda usar métodos asincrónicos en el controlador OnRequestReceived .A deferral is taken so that the service can use async methods in the OnRequestReceived handler. Garantiza que la llamada a OnRequestReceived no se completa hasta que se termina de procesar el mensaje.It ensures that the call to OnRequestReceived does not complete until it is done processing the message. SendResponseAsync envía el resultado al llamador.SendResponseAsync sends the result to the caller. SendResponseAsync no indica la finalización de la llamada.SendResponseAsync does not signal the completion of the call. Se trata de la finalización del aplazamiento que señala a SendMessageAsync que OnRequestReceived se ha completado.It is the completion of the deferral that signals to SendMessageAsync that OnRequestReceived has completed. La llamada a SendResponseAsync se ajusta en un bloque try/finally porque debe completar el aplazamiento incluso si SendResponseAsync produce una excepción.The call to SendResponseAsync is wrapped in a try/finally block because you must complete the deferral even if SendResponseAsync throws an exception.

Los servicios de aplicaciones usan objetos ValueSet para intercambiar información.App services use ValueSet objects to exchange information. El tamaño de los datos que se pueden pasar solo está limitado por los recursos del sistema.The size of the data you may pass is only limited by system resources. No hay claves predefinidas para su uso en el elemento ValueSet.There are no predefined keys for you to use in your ValueSet. Debes determinar qué valores clave usarás para definir el protocolo del servicio de aplicaciones.You must determine which key values you will use to define the protocol for your app service. Debes escribir el llamador teniendo ese protocolo presente.The caller must be written with that protocol in mind. En este ejemplo, se ha elegido una clave denominada Command que tiene un valor que indica si se desea que App Service proporcione el nombre del artículo de inventario o su precio.In this example, we have chosen a key named Command that has a value that indicates whether we want the app service to provide the name of the inventory item or its price. El índice del nombre del inventario se almacena en la ID clave.The index of the inventory name is stored under the ID key. El valor devuelto se almacena en la Result clave.The return value is stored under the Result key.

Se devuelve al llamador una enumeración AppServiceClosedStatus para indicar si la llamada al servicio de aplicaciones se ha realizado correctamente o no.An AppServiceClosedStatus enum is returned to the caller to indicate whether the call to the app service succeeded or failed. Un ejemplo de cómo se puede producir un error en la llamada a App Service es si el sistema operativo anula el punto de conexión de servicio porque se han superado sus recursos.An example of how the call to the app service could fail is if the OS aborts the service endpoint because its resources have been exceeded. Puedes devolver información adicional sobre errores a través de ValueSet.You can return additional error information via the ValueSet. En este ejemplo, usamos una clave denominada Status para devolver información más detallada sobre el error al autor de la llamada.In this example, we use a key named Status to return more detailed error information to the caller.

La llamada a SendResponseAsync devuelve el elemento ValueSet al llamador.The call to SendResponseAsync returns the ValueSet to the caller.

Implementar el servicio de aplicaciones y obtener el nombre de familia de paqueteDeploy the service app and get the package family name

El proveedor de App Service debe implementarse para poder llamarlo desde un cliente.The app service provider must be deployed before you can call it from a client. Puede implementarlo seleccionando Compilar > implementar solución en Visual Studio.You can deploy it by selecting Build > Deploy Solution in Visual Studio.

También necesitará el nombre de familia del paquete del proveedor de App Service para llamarlo.You will also need the package family name of the app service provider in order to call it. Para obtenerlo, abra el archivo Package. appxmanifest del proyecto AppServiceProvider en la vista del diseñador (haga doble clic en él en el Explorador de soluciones).You can get it by opening the AppServiceProvider project's Package.appxmanifest file in the designer view (double-click it in the Solution Explorer). Seleccione la pestaña empaquetado , copie el valor junto a nombre de familia de paquetey péguelo en un lugar como el Bloc de notas por ahora.Select the Packaging tab, copy the value next to Package family name, and paste it somewhere like Notepad for now.

Escribir un cliente para llamar al servicio de aplicacionesWrite a client to call the app service

  1. Agregue un nuevo proyecto de aplicación universal de Windows en blanco a la solución con el archivo > agregar > nuevo proyecto.Add a new blank Windows Universal app project to the solution with File > Add > New Project. En el cuadro de diálogo Agregar nuevo proyecto , elija instalado > Visual C# > aplicación vacía (Windows universal) y asígnele el nombre ClientApp.In the Add New Project dialog box, choose Installed > Visual C# > Blank App (Universal Windows) and name it ClientApp.

  2. En el proyecto ClientApp , agregue la siguiente instrucción using a la parte superior de mainpage.Xaml.CS:In the ClientApp project, add the following using statement to the top of MainPage.xaml.cs:

    using Windows.ApplicationModel.AppService;
    
  3. Agregue un cuadro de texto denominado textBox y un botón a mainpage. Xaml.Add a text box called textBox and a button to MainPage.xaml.

  4. Agregue un controlador de clic de botón para el botón llamado button_Clicky agregue la palabra clave Async a la firma del controlador de botón.Add a button click handler for the button called button_Click, and add the keyword async to the button handler's signature.

  5. Reemplaza el código auxiliar del controlador de clic del botón por el siguiente código.Replace the stub of your button click handler with the following code. Asegúrate de incluir la declaración de campo inventoryService.Be sure to include the inventoryService field declaration.

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

    Reemplace el nombre de la familia del paquete en la línea this.inventoryService.PackageFamilyName = "Replace with the package family name"; con el nombre de familia del paquete del proyecto AppServiceProvider que obtuvo anteriormente en implementación de la aplicación de servicio y obtenga el nombre de familia del paquete.Replace the package family name in the line this.inventoryService.PackageFamilyName = "Replace with the package family name"; with the package family name of the AppServiceProvider project that you obtained above in Deploy the service app and get the package family name.

    Nota

    Asegúrese de pegar en el literal de cadena, en lugar de colocarlo en una variable.Make sure to paste in the string literal, rather than putting it in a variable. No funcionará si usa una variable.It will not work if you use a variable.

    En primer lugar, el código establece una conexión con el servicio de aplicaciones.The code first establishes a connection with the app service. La conexión permanecerá abierta hasta que se elimine this.inventoryService .The connection will remain open until you dispose this.inventoryService. El nombre de App Service debe coincidir con el AppService atributo del elemento Name que agregó al archivo Package. Appxmanifest del proyecto AppServiceProvider .The app service name must match the AppService element's Name attribute that you added to the AppServiceProvider project's Package.appxmanifest file. En este ejemplo, es <uap3:AppService Name="com.microsoft.inventory"/>.In this example, it is <uap3:AppService Name="com.microsoft.inventory"/>.

    Se crea un ValueSet denominado message para especificar el comando que se desea enviar a App Service.A ValueSet named message is created to specify the command that we want to send to the app service. El servicio de aplicaciones de ejemplo espera un comando para indicar qué dos acciones realizar.The example app service expects a command to indicate which of two actions to take. Obtenemos el índice en el cuadro de texto de la aplicación cliente y, a continuación, llamaremos al servicio con el Item comando para obtener la descripción del elemento.We get the index from the text box in the client app, and then call the service with the Item command to get the description of the item. A continuación, realizamos la llamada con el Price comando para obtener el precio del artículo.Then, we make the call with the Price command to get the item's price. El texto del botón se define en el resultado.The button text is set to the result.

    Dado que AppServiceResponseStatus solo indica si el sistema operativo pudo conectar la llamada a App Service, comprobamos la Status clave de la instancia de ValueSet que recibimos de App Service para asegurarse de que pudo completar la solicitud.Because AppServiceResponseStatus only indicates whether the operating system was able to connect the call to the app service, we check the Status key in the ValueSet we receive from the app service to ensure that it was able to fulfill the request.

  6. Establezca el proyecto ClientApp en el proyecto de inicio (haga clic con el botón secundario en el Explorador de soluciones > establecer como proyecto de inicio) y ejecute la solución.Set the ClientApp project to be the startup project (right-click it in the Solution Explorer > Set as StartUp Project) and run the solution. Escribe el número 1 en el cuadro de texto y haz clic en el botón.Enter the number 1 into the text box and click the button. El servicio debería devolver "Chair : Price = 88.99".You should get "Chair : Price = 88.99" back from the service.

    aplicación de muestra que muestra el precio de la silla=88.99

Si se produce un error en la llamada de App Service, compruebe lo siguiente en el proyecto ClientApp :If the app service call fails, check the following in the ClientApp project:

  1. Compruebe que el nombre de familia del paquete asignado a la conexión del servicio de inventario coincide con el nombre de familia del paquete de la aplicación AppServiceProvider .Verify that the package family name assigned to the inventory service connection matches the package family name of the AppServiceProvider app. Vea el botón de línea en ** _ haga clic** con this.inventoryService.PackageFamilyName = "..."; .See the line in button_Click with this.inventoryService.PackageFamilyName = "...";.
  2. En ** _ haga clic**en el botón, compruebe que el nombre de App Service que se asigna a la conexión del servicio de inventario coincide con el nombre del servicio de la aplicación en el archivo Package. appxmanifest de AppServiceProvider.In button_Click, verify that the app service name that is assigned to the inventory service connection matches the app service name in the AppServiceProvider's Package.appxmanifest file. Consulta: this.inventoryService.AppServiceName = "com.microsoft.inventory";.See: this.inventoryService.AppServiceName = "com.microsoft.inventory";.
  3. Asegúrese de que se ha implementado la aplicación AppServiceProvider .Ensure that the AppServiceProvider app has been deployed. (En el Explorador de soluciones, haga clic con el botón secundario en la solución y elija implementar solución).(In the Solution Explorer, right-click the solution and choose Deploy Solution).

Depurar el servicio de aplicacionesDebug the app service

  1. Asegúrese de que la solución se implementa antes de la depuración porque se debe implementar la aplicación del proveedor de App Service antes de que se pueda llamar al servicio.Ensure that the solution is deployed before debugging because the app service provider app must be deployed before the service can be called. (En Visual Studio, Compilar > Implementar solución).(In Visual Studio, Build > Deploy Solution).
  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto AppServiceProvider y elija propiedades.In the Solution Explorer, right-click the AppServiceProvider project and choose Properties. Desde la pestaña Depurar cambia Acción de inicio a No iniciar, pero depurar mi código al empezar.From the Debug tab, change the Start action to Do not launch, but debug my code when it starts. (Tenga en cuenta que, si usa C++ para implementar su proveedor de servicios de aplicaciones, en la pestaña depuración se cambiaría la aplicación de inicio a no).(Note, if you were using C++ to implement your app service provider, from the Debugging tab you would change Launch Application to No).
  3. En el proyecto MyAppService , en el archivo Inventory.CS , establezca un punto de interrupción en OnRequestReceived.In the MyAppService project, in the Inventory.cs file, set a breakpoint in OnRequestReceived.
  4. Establezca el proyecto AppServiceProvider en el proyecto de inicio y presione F5.Set the AppServiceProvider project to be the startup project and press F5.
  5. Inicie ClientApp desde el menú Inicio (no desde Visual Studio).Start ClientApp from the Start menu (not from Visual Studio).
  6. Escribe el número 1 en el cuadro de texto y presiona el botón.Enter the number 1 into the text box and press the button. El depurador se detendrá en la llamada al servicio de aplicaciones en el punto de interrupción del servicio de aplicaciones.The debugger will stop in the app service call on the breakpoint in your app service.

Depurar el clienteDebug the client

  1. Siga las instrucciones del paso anterior para depurar el cliente que llama a App Service.Follow the instructions in the preceding step to debug the client that calls the app service.
  2. Inicie ClientApp desde el menú Inicio.Launch ClientApp from the Start menu.
  3. Adjunte el depurador al proceso de ClientApp.exe (no al proceso de ApplicationFrameHost.exe ).Attach the debugger to the ClientApp.exe process (not the ApplicationFrameHost.exe process). (En Visual Studio, elige Depurar > Asociar al proceso…)(In Visual Studio, choose Debug > Attach to Process....)
  4. En el proyecto ClientApp , establezca un punto de interrupción en el botón _ clic.In the ClientApp project, set a breakpoint in button_Click.
  5. Ahora se alcanzarán los puntos de interrupción tanto en el cliente como en el servicio de aplicaciones cuando escriba el número 1 en el cuadro de texto de ClientApp y haga clic en el botón.The breakpoints in both the client and the app service will now be hit when you enter the number 1 into the text box of ClientApp and click the button.

Solución de problemas generales de App ServiceGeneral app service troubleshooting

Si encuentra un estado de AppUnavailable después de intentar conectarse a un servicio de aplicaciones, compruebe lo siguiente:If you encounter an AppUnavailable status after trying to connect to an app service, check the following:

  • Asegúrese de que se han implementado el proyecto de proveedor de App Service y el proyecto de App Service.Ensure that the app service provider project and app service project are deployed. Ambos deben implementarse antes de ejecutar el cliente porque, de lo contrario, el cliente no tendrá ningún elemento al que conectarse.Both need to be deployed before running the client because otherwise the client won't have anything to connect to. Puede implementar desde Visual Studio mediante la solución de implementación de compilación > Deploy Solution.You can deploy from Visual Studio by using Build > Deploy Solution.
  • En el Explorador de soluciones, asegúrese de que el proyecto de proveedor de App Service tiene una referencia de proyecto a proyecto al proyecto que implementa App Service.In the Solution Explorer, ensure that your app service provider project has a project-to-project reference to the project that implements the app service.
  • Compruebe que la <Extensions> entrada y sus elementos secundarios se han agregado al archivo Package. appxmanifest que pertenece al proyecto de proveedor de App Service, tal y como se especificó anteriormente en Agregar una extensión de App Service a package. appxmanifest.Verify that the <Extensions> entry, and its child elements, have been added to the Package.appxmanifest file belonging to the app service provider project as specified above in Add an app service extension to Package.appxmanifest.
  • Asegúrese de que la cadena AppServiceConnection. AppServiceName del cliente que llama al proveedor de App Service coincide con la <uap3:AppService Name="..." /> especificada en el archivo Package. appxmanifest del proyecto del proveedor de App Service.Ensure that the AppServiceConnection.AppServiceName string in your client that calls the app service provider matches the <uap3:AppService Name="..." /> specified in the app service provider project's Package.appxmanifest file.
  • Asegúrese de que AppServiceConnection. PackageFamilyName coincide con el nombre de familia del paquete del componente de proveedor de App Service tal y como se especificó anteriormente en Agregar una extensión de App Service a package. appxmanifest.Ensure that the AppServiceConnection.PackageFamilyName matches the package family name of the app service provider component as specified above in Add an app service extension to Package.appxmanifest
  • En el caso de los servicios de aplicaciones fuera de proceso, como el de este ejemplo, compruebe que el EntryPoint especificado en el <uap:Extension ...> elemento del archivo Package. appxmanifest del proyecto de App Service Provider coincide con el espacio de nombres y el nombre de clase de la clase pública que implementa IBackgroundTask en el proyecto de App Service.For out-of-proc app services such as the one in this example, validate that the EntryPoint specified in the <uap:Extension ...> element of your app service provider project's Package.appxmanifest file matches the namespace and class name of the public class that implements IBackgroundTask in your app service project.

Solución de problemas de depuraciónTroubleshoot debugging

Si el depurador no se detiene en los puntos de interrupción en el proveedor de App Service o en los proyectos de App Service, compruebe lo siguiente:If the debugger does not stop at breakpoints in your app service provider or app service projects, check the following:

  • Asegúrese de que se han implementado el proyecto de proveedor de App Service y el proyecto de App Service.Ensure that the app service provider project and app service project are deployed. Ambos deben implementarse antes de ejecutar el cliente.Both need to be deployed before running the client. Puede implementarlos desde Visual Studio mediante la implementación de la solución de compilación > Deploy Solution.You can deploy them from Visual Studio by using Build > Deploy Solution.
  • Asegúrese de que el proyecto que desea depurar se establece como el proyecto de inicio y que las propiedades de depuración de ese proyecto están configuradas para no ejecutar el proyecto cuando se presiona F5 .Ensure that the project you want to debug is set as the startup project and that the debugging properties for that project are set to not run the project when F5 is pressed. Haga clic con el botón secundario en el proyecto, haga clic en propiedadesy, a continuación, en depurar (o depurar en C++).Right-click the project, then click Properties, and then Debug (or Debugging in C++). En C#, cambie la acción de inicio a no iniciar, pero depure mi código cuando se inicie.In C#, change the Start action to Do not launch, but debug my code when it starts. En C++, establezca Iniciar aplicación en no.In C++, set Launch Application to No.

ObservacionesRemarks

Este ejemplo proporciona una introducción a la creación de una aplicación de App Service que se ejecuta como una tarea en segundo plano y la llama desde otra aplicación.This example provides an introduction to creating an app service that runs as a background task and calling it from another app. Los aspectos clave que hay que tener en cuenta son:The key things to note are:

  • Cree una tarea en segundo plano para hospedar el servicio de aplicaciones.Create a background task to host the app service.
  • Agregue la windows.appService extensión al archivo Package. appxmanifest del proveedor de App Service.Add the windows.appService extension to the app service provider's Package.appxmanifest file.
  • Obtenga el nombre de familia del paquete del proveedor de App Service para que podamos conectarse a él desde la aplicación cliente.Obtain the package family name of the app service provider so that we can connect to it from the client app.
  • Agregue una referencia de proyecto a proyecto del proyecto de proveedor de App Service al proyecto de App Service.Add a project-to-project reference from the app service provider project to the app service project.
  • Use Windows. ApplicationModel. AppService. AppServiceConnection para llamar al servicio.Use Windows.ApplicationModel.AppService.AppServiceConnection to call the service.

Código completo para MyAppServiceFull code for 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();
            }
        }
    }
}