Operaciones sincrónicas y asincrónicas
Describe implementaciones asincrónicas locales e invocaciones, así como el uso sincrónico de intercambios de mensajes asincrónicos.
Muchas aplicaciones llaman de forma asincrónica a los métodos porque permite que la aplicación siga realizando trabajo útil mientras se ejecuta la llamada al método. Los servicios y clientes Windows Communication Foundation (WCF) pueden participar en llamadas de operación asincrónicas en dos niveles distintos de la aplicación, que proporcionan a las aplicaciones WCF aún más flexibilidad para maximizar el rendimiento buscando el equilibrio con la interactividad.
Tipos de operaciones asincrónicas
Todos los contratos de servicio en WCF, sin tener en cuenta los tipos de parámetros y valores de retorno, usan atributos WCF para especificar un determinado modelo de intercambio de mensajes entre el cliente y el servicio. WCF enruta automáticamente mensajes de entrada y salida a la operación de servicio adecuada o al código de cliente ejecutor.
El cliente posee sólo el contrato de servicio, que especifica el modelo de intercambio de mensajes para una operación determinada. Los clientes pueden ofrecer cualquier modelo de programación que elijan al programador, siempre y cuando se observe el modelo de intercambio de mensajes subyacente. Así, también, los servicios pueden implementar operaciones de cualquier manera, siempre que se observe el modelo del mensaje especificado.
La independencia del contrato de servicio del servicio o de la implementación del cliente habilita los formularios siguientes de ejecución asincrónica en aplicaciones WCF:
- Los clientes pueden invocar operaciones de solicitud/respuesta asincrónicamente mediante un intercambio de mensajes sincrónico.
- Los servicios pueden implementar una operación de solicitud/respuesta asincrónicamente mediante un intercambio de mensajes sincrónico.
- Los intercambios de mensajes pueden ser unidireccionales, sin tener en cuenta la implementación del cliente o servicio.
Escenarios asincrónicos sugeridos
Use un enfoque asincrónico en una implementación de operación de servicio si la implementación del servicio de la operación realiza una llamada en bloque, como al realizar operaciones de E/S. En una implementación de operación asincrónica, intente llamar a métodos y operaciones asincrónicos para extender la ruta de acceso de la llamada asincrónica al máximo. Por ejemplo, llame a una BeginOperationTwo()
desde BeginOperationOne()
.
- Use un enfoque asincrónico en una aplicación de cliente o que realiza la llamada en los casos siguientes:
- Si invoca operaciones desde una aplicación de nivel intermedio. (Para obtener más información acerca de estos escenarios, consulte Aplicaciones cliente de nivel intermedio.)
- Si invoca operaciones desde una página ASP.NET, use páginas asincrónicas.
- Si invoca operaciones desde cualquier aplicación de proceso simple, como Windows Forms o Windows Presentation Foundation (WPF). Si utiliza el modelo de llamada asincrónica basado en evento, el evento resultante se produce en el proceso de interfaz de usuario, agregando capacidad de respuesta a la aplicación sin que sea necesario controlar procesos múltiples.
- En general, si puede elegir entre una llamada sincrónica y una asincrónica, elija la asincrónica.
Llamadas asincrónicas del cliente
Una aplicación de cliente WCF puede utilizar uno o dos modelos de llamada asincrónica, ambos descritos en Asynchronous Programming Design Patterns:
- Operaciones asincrónicas que utilizan eventos.
- Operaciones asincrónicas que utilizan objetos System.IAsyncResult.
El primer enfoque, el modelo asincrónico basado en eventos, se recomienda para llamar a aplicaciones, ya que sólo requiere agregar un controlador de eventos para recibir una notificación de la respuesta, y el evento resultante que se genera automáticamente en el proceso de la interfaz de usuario. Para aplicar este enfoque, especifique las opciones de comando /async y /tcv:Version35 con la ServiceModel Metadata Utility Tool (Svcutil.exe), como en el ejemplo siguiente.
svcutil https://localhost:8000/servicemodelsamples/service/mex /async /tcv:Version35
Una vez hecho esto, Svcutil.exe genera una clase de cliente WCF con la infraestructura de cliente que permite a la aplicación de llamada implementar y asignar un controlador de eventos para recibir la respuesta y realizar la acción apropiada. Para obtener un ejemplo completo, consulte Cómo llamar a operaciones del servicio WCF de forma asincrónica.
El modelo asincrónico basado en eventos, sin embargo, sólo está disponible en .NET Framework versión 3.5. Además, no está permitido ni en .NET Framework 3,5 cuando se crea un canal de cliente WCF mediante System.ServiceModel.ChannelFactory. Con objetos de canal de cliente WCF, debe utilizar objetos System.IAsyncResult para invocar sus operaciones asincrónicamente. Para aplicar este enfoque, especifique la opción de comando /async con la ServiceModel Metadata Utility Tool (Svcutil.exe), como en el ejemplo siguiente.
svcutil https://localhost:8000/servicemodelsamples/service/mex /async
Esto genera un contrato de servicio en el cual cada operación se modela como un método <Begin> con la propiedad AsyncPattern establecida en true y un método <End> correspondiente. Para obtener un ejemplo completo mediante ChannelFactory, vea Cómo llamar a operaciones de manera asincrónica mediante un generador de canales.
En cualquier caso, las aplicaciones pueden invocar una operación asincrónicamente aun cuando se implementa el servicio sincrónicamente, del mismo modo que una aplicación puede usar el mismo modelo para invocar de forma asincrónica un método sincrónico local. Cómo se implementa la operación no es significativo para el cliente; cuando llega el mensaje de respuesta, su contenido se envía al método <End> de extremo asincrónico del cliente y el cliente recupera la información.
Implementaciones de operación asincrónica
Igualmente, una operación de servicio se puede implementar asincrónicamente mediante el modelo de programación asincrónico .NET Framework y marcando el método <Begin> con la propiedad AsyncPattern establecida en true. En este caso, la operación asincrónica se expone en metadatos de la misma manera que una operación síncrona: se expone como una operación única con un mensaje de solicitud y un mensaje de respuesta correlativo. Los modelos de programación de cliente tienen entonces una opción. Pueden representar este modelo como una operación síncrona o como una asincrónica, siempre que se origine un intercambio de mensajes solicitud-respuesta cuando se invoque el servicio.
Para ver un ejemplo, consulte Cómo: Implementar una operación de servicios asincrónica.
Para definir una operación de contrato X
que se ejecuta asincrónicamente sin tener en cuenta cómo se llama en la aplicación cliente:
- Defina dos métodos mediante el modelo BeginOperation y EndOperation.
- El método BeginOperation incluye parámetros in y out para la operación y devuelve un tipo IAsyncResult.
- El método EndOperation incluye un parámetro IAsyncResult así como los parámetros out y in y devuelve el tipo de valor devuelto de las operaciones.
Por ejemplo, vea el método siguiente.
int DoWork(string data, ref string inout, out string outonly)
Function DoWork(ByVal data As String, ByRef inout As String, _
out outonly As out) As Integer
Para crear una operación asincrónica, los dos métodos serían:
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginDoWork(string data,
ref string inout,
AsyncCallback callback,
object state);
int EndDoWork(ref string inout, out string outonly, IAsyncResult result);
<OperationContract(AsyncPattern := True)> _
Function BeginDoWork(ByVal data As String, _
ByRef inout As String, _
ByVal callback As AsyncCallback, _
ByVal state As Object) _
As IAsyncResult
Function EndDoWork(ByRef inout As String, _
ByRef outonly As String, _
ByVal result As IAsyncResult) _
As Integer
Nota
El atributo OperationContractAttribute se aplica solamente a los métodos de BeginDoWork
. El contrato resultante tiene una operación WSDL denominada DoWork
.
Modelos de intercambio de mensajes unidireccional
También puede crear un modelo de intercambio de mensajes asincrónico en el que las operaciones unidireccionales (las operaciones para las que System.ServiceModel.OperationContractAttribute.IsOneWay es true no tienen ninguna respuesta puesta en correlación) se pueden enviar en cualquier dirección por el cliente o por el servicio, independientemente del otro lado. (Esto utiliza el modelo de intercambio de mensajes dúplex con mensajes unidireccionales.) En este caso, el contrato de servicio especifica un intercambio de mensajes unidireccional que cada parte puede implementar como llamadas asincrónicas o implementaciones, o no, según corresponda. Por lo general, cuando el contrato es un intercambio de mensajes unidireccionales, las implementaciones pueden ser muchas veces sincrónicas porque una vez se envía un mensaje, la aplicación no espera a una respuesta y puede continuar haciendo otro trabajo.
Clientes asincrónicos y contratos de mensajes basados en eventos
Las directrices de diseño del modelo asincrónico basado en eventos afirman que si se devuelve más de un valor, uno de los valores se devuelve como propiedad Result y los demás se devuelven como propiedades del objeto EventArgs. De esto resulta que si un cliente importa metadatos mediante opciones de comando asincrónicas basadas en eventos y la operación devuelve más de un valor, el objeto EventArgs predeterminado devuelve un valor como propiedad Result y el resto son propiedades del objeto EventArgs.
Si desea recibir el objeto del mensaje como propiedad Result y que los valores devueltos sean propiedades de ese objeto, use la opción de comando /messageContract. Esto genera una firma que devuelve el mensaje de respuesta como la propiedad Result del objeto EventArgs. Todos los valores de devolución internos se convierten, pues, en propiedades del objeto de mensaje de respuesta.