2010-10-12 4 views
6

J'ai créé un simple service wcf hébergé dans un client IIS et wcf et ai compris que lorsque vous attrapez une exception FaultException du service wcf, puis appelez le client. Abort() pour libérer la session (comme les microsoft dit les échantillons) il ne libère pas la session et raccroche au 11ème appel.La méthode Abort() du proxy client wcf ne libère pas la session après avoir intercepté FaultException

Voici par exemple:

WCF Service:

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

Client:

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

}

Mais si vous remplacez le client.Abort() avec client.Close() pour catch (FaultException) alors tout fonctionne comme un charme et il n'y a pas de verrouillage après le 11ème appel de la wcf méthode de service Pourquoi cela pourrait-il être? Pourquoi la méthode Abort() ne nettoie pas la session après que FaultException a été interceptée?

+2

Est-ce que vous venez de copier collé d'ici? http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/f86c056a-4027-453a-a46c-fc223e03589b/ – oleksii

Répondre

2

Avez-vous essayé de cette façon, que j'utilise pour appeler 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

Cette réponse serait plus utile si elle comprenait une explication de pourquoi vous utilisez cette méthode . –

5

Deux choses:

  • Abort() doit être utilisé lorsque le canal de communication est dans un état irréprochable. L'utilisation de Close() permet au client d'essayer de communiquer avec le service, en lui disant de fermer l'instance de service, comme si vous le vouliez. Si le canal de communication est dans l'état Faulted, cela signifie qu'aucune communication ne peut être effectuée du client au service. Dans cette situation, vous devez appeler Abort() afin qu'au moins le client soit fermé. L'instance/session de service sera toujours active sur le serveur (puisqu'il n'y a pas de communication entre les deux), et le restera jusqu'à ce que le délai d'attente de l'instance se produise. Si vous aviez appelé Close() sur un canal défectueux, cela aurait généré plus d'erreurs. Votre service envoie un FaultException. Cela ne signifie pas que le canal de communication sera mis en défaut. c'est-à-dire que vous pouvez toujours passer des appels en utilisant le même client. Et en tant que tel, dans votre exemple, vous ne devriez pas appeler Abort().

tl; drAbort() ferme seulement le client. L'instance/session de service est toujours en vie.

Vous pouvez vérifier l'état de canal de communication en utilisant:

ICommunicationObject comObj = ((ICommunicationObject)client); 
if(comObj.State == CommunicationState.Faulted) 
    client.Abort(); 
else 
    client.Close(); 
Questions connexes