2010-10-12 15 views
6

He creado un servicio WCF sencilla alojado en IIS y WCF cliente y dado cuenta de que cuando u coger un FaultException del servicio WCF y luego llamada del cliente. Abort() para lanzar la sesión (como dijeron las muestras de Microsoft) no libera la sesión y se cuelga en la 11ma llamada.Abortar() de proxy de cliente WCF no libera la sesión después de la captura FaultException

Aquí es ejemplo:

WCF Servicio:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    string GetData(int value); 
} 


public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     throw new FaultException("Exception is here"); 

     return string.Format("You entered: {0}", value); 
    } 
} 

Cliente:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Service1Client client = null;   

     for(int i = 0; i < 15; i++) 
     { 
      try 
      { 
       client = new Service1Client(); 
       client.GetData(100);     
      } 
      catch (TimeoutException timeoutEx) 
      { 
       Console.WriteLine(timeoutEx); 
       client.Abort(); 
      } 
      catch (FaultException faultEx) 
      { 
       Console.WriteLine(faultEx); 
       client.Abort(); 
      } 
      catch (CommunicationException commEx) 
      { 
       Console.WriteLine(commEx); 
       client.Abort(); 
      } 
     } 
    }    

}

Pero si sustituye la client.Abort() con client.Close() para atrapar (FaultException) entonces todo funciona como un amuleto y no hay bloqueo después de la 11ma llamada del wcf -servicio de servicio.

Por qué podría ser? ¿Por qué el método Abort() no limpia la sesión después de atrapar FaultException?

+2

lo que acabas de copia pegada desde aquí? http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/f86c056a-4027-453a-a46c-fc223e03589b/ – oleksii

Respuesta

2

Ha intentado de esta manera, que utilizo para llamar WCF?

class Program 
{ 
static void Main(string[] args) 
{ 
    for(int i = 0; i < 15; i++) 
    { 
     using Service1Client client = new Service1Client() 
     { 
     try 
     { 
      client.GetData(100);     
     } 
     catch (TimeoutException timeoutEx) 
     { 
      Console.WriteLine(timeoutEx); 
      client.Abort(); 
     } 
     catch (FaultException faultEx) 
     { 
      Console.WriteLine(faultEx); 
      client.Abort(); 
     } 
     catch (CommunicationException commEx) 
     { 
      Console.WriteLine(commEx); 
      client.Abort(); 
     } 
     finally 
     { 
      client.Close(); 
     } 
     } 
    } 
}    
+0

Esta respuesta sería más útil si se incluía una explicación de por qué se utiliza este método . –

5

dos cosas:

  • Abort() se debe utilizar cuando el canal de comunicación está en un estado de fallo. El uso de Close() hace que el cliente intente comunicarse con el servicio, diciéndole que cierre la instancia del servicio, de forma elegante, si así lo desea. Si el canal de comunicación está en estado de falla, significa que no se puede hacer ninguna comunicación entre el cliente y el servicio. En esa situación, debe llamar al Abort() para que al menos el cliente esté cerrado. La instancia/sesión del servicio seguirá activa en el servidor (ya que no hay comunicación entre los dos) y seguirá siéndolo hasta que se produzca el tiempo de espera de la instancia. Si llamaras al Close() en un canal con falla, habría arrojado más errores.
  • Su servicio es lanzar una FaultException. Esto no significa que el Canal de Comunicación se pondrá en estado de falla. es decir, todavía puedes hacer llamadas usando el mismo cliente. Y como tal, en su ejemplo no debería llamar al Abort().

tl; drAbort() sólo cierra el cliente. La instancia/sesión de servicio aún está activa.

Puede comprobar el estado del canal de comunicación mediante el uso de:

ICommunicationObject comObj = ((ICommunicationObject)client); 
if(comObj.State == CommunicationState.Faulted) 
    client.Abort(); 
else 
    client.Close(); 
Cuestiones relacionadas