2011-10-04 10 views
5

Estamos consumiendo servicios wcf en la aplicación silverlight a través de la creación de proxies usando ChanellFacotry.Llamar sincrónicamente a los métodos de contrato de operación WCF en silverlight

Los contratos de Operación y Datos están expuestos al conjunto de canales Silverlight, que consta de archivos compartidos de datos del servidor y de contratos de operación. (omg Espero que entiendas lo que estoy diciendo).

Por lo tanto, el servidor y el cliente están utilizando los mismos contratos de operación y datos.

Silverlight wcf client lib tiene una restricción para no poder llamar a los métodos wcf de forma síncrona, como saben, por lo que el archivo de contratos de operación compartida debe exponer las versiones asyn de cada operación.

Escribir el servicio asíncrono WCF tendría algún sentido si no estuvieran conteniendo operaciones de bloqueo, pero como usamos EF, asyncrhony se logra al delegar el trabajo de bloqueo al grupo de subprocesos. Esto es lo que hace WCF para los métodos de sincronización de todos modos. Y este hecho me da ganas de arrancarme los ojos (# @%! ^%! @%).

Nuestro consultor de proyectos tiene la capacidad de no permitir la generación de proxies dinámicos en el cliente para llamar a los métodos de contrato de operación de sincronización (google Yevhen Bobrov Servelat Pieces si usted está interesado). Así que tenemos que escribir implementaciones de senseles de métodos asíncronos en el servidor, sin ninguna ganancia de rendimiento (bloqueando llamadas como lo recuerdas).

¿Es posible llamar al método síncrono del servicio web wcf de silverlight utilizando su contrato de datos?

¿Alguna vez ha enfrentado este problema antes? De ser así, ¿cómo lo resolvió?

En el momento en el que estoy esperando generar contratos asíncronos solo para el cliente utilizando contratos en el servidor como fuente de transformación. ¿Tal vez hay alguna plantilla t4 que puede hacerla bien por mí?

Lo siento por el muro de texto, sólo para mezclar un poco de código a mi pregunta, esta es la forma en la ejecución del contrato asíncrono mira al momment:

/// <summary> 
    /// Subscribes to users of the specified organization. 
    /// </summary> 
    /// <param name="organizationId">The organization id.</param> 
    public void Unsubscribe(int organizationId) 
    { 
     var clientId = this.OperationContext.GetClientId(); 
     if (string.IsNullOrEmpty(clientId)) 
     { 
      return; 
     } 

     this.InternalUnsubscribe(organizationId, clientId); 
    } 

    /// <summary> 
    /// Begins an asynchronous operation to Unsubscribe. 
    /// </summary> 
    /// <param name="organizationId">The organization id.</param> 
    /// <param name="callback">The callback.</param> 
    /// <param name="passThroughData">The pass through data.</param> 
    /// <returns> 
    /// An implementation of <see cref="IAsyncResult"/> that provides access to the state or result of the operation. 
    /// </returns> 
    public IAsyncResult BeginUnsubscribe(int organizationId, AsyncCallback callback, object passThroughData) 
    { 
     var clientId = this.OperationContext.GetClientId(); 
     if (string.IsNullOrEmpty(clientId)) 
     { 
      return null; 
     } 

     var asyncResult = new VoidAsyncResult(callback, passThroughData); 
     Task.Factory.StartNew(() => 
      { 
       try 
       { 
        this.InternalUnsubscribe(organizationId, clientId); 
        asyncResult.SetAsCompleted(false); 
       } 
       catch (Exception ex) 
       { 
        asyncResult.SetAsCompleted(ex, false); 
       } 
      }); 
     return asyncResult; 
    } 

    /// <summary> 
    /// Ends an existing asynchronous operation to Unsubscribe. 
    /// </summary> 
    /// <param name="result">The <see cref="IAsyncResult"/> provided by the BeginUnsubscribe operation.</param> 
    public void EndUnsubscribe(IAsyncResult result) 
    { 
     var response = result as VoidAsyncResult; 
     if (response != null) 
     { 
      response.EndInvoke(); 
     } 
    } 

Respuesta

3

No es necesario escribir el servicio WCF para ser asíncrono . Simplemente necesita hacer un ServiceContract para su servicio que define los métodos Async. Aquí hay un ejemplo rápido

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    int Foo(string input); 
} 

//tell wcf that this contract applies to IMyService 
[ServiceContract(Name = "IMyService")] 
public interface IMyServiceAsync 
{ 
    //setting AsyncPattern = true allows WCF to map the async methods to the sync ones. 
    [OperationContract(AsyncPattern = true)] 
    IAsyncResult BeginFoo(string input, AsyncCallback callback, object asyncState); 

    int EndFoo(IAsyncResult result}; 
} 

// you only need to implement the sync contract 
public class MyService : IMyService 
{ 
    public int Foo(string input) 
    { 
     return input.Length; 
    } 
} 

Ahora use IMyServiceAsync con su ChannelFactory y todo debería funcionar.

+0

Gracias, acabo de encontrar una plantilla t4 que puede hacer esta transformación, probarla ahora. – v00d00

+0

Avísame cómo funciona. He tenido la intención de buscar t4 para hacer esto, pero no he tenido el tiempo. – cadrell0

+0

Su falla, intentará especificar el nombre de la operación explícitamente – v00d00

Cuestiones relacionadas