2009-10-12 5 views
7

Je reproché essaie de mettre en œuvre une logique de rebranchement pour un client WCF. Je suis conscient que vous devez créer un nouveau canal après que le canal actuel est entré dans l'état défectueux. Je l'ai fait dans un gestionnaire d'événements en défaut de canal:WCF canal Callback


internal class ServiceClient : DuplexClientBase, IServiceClient 
{ 
    public ServiceClient(ICallback callback, EndpointAddress serviceAddress) 
    : base(callback, MyUtility.GetServiceBinding("NetTcpBinding"), serviceAddress) 
    { 
    // Open the connection. 
    Open(); 
    } 

    public void Register(string clientName) 
    { 
    // register to service 
    } 

    public void DoSomething() 
    { 
    // some code 
    } 
} 

public class ClientApp 
{ 
    private IServiceClient mServiceClient; 

    private ICallback mCallback; 

    public ClientApp() 
    { 
    mServiceClient = new ServiceClient(mCallback, new EndpointAddress("someAddress")); 

    mServiceClient.Register(); 

    // register faulted event for the service client 
    ((ICommunicationObject)mServiceClient).Faulted += new EventHandler(ServiceClient_Faulted); 
    } 

    void ServiceClient_Faulted(object sender, EventArgs e) 
    { 
    // Create new Service Client. 
    mServiceClient = new ServiceClient(mCallback, new EndpointAddress("someAddress")); 

    // Register the EI at Cell Controller 
    mServiceClient.Register(); 
    } 

    public void DoSomething() 
    { 
    mServiceClient.DoSomething(); 
    } 
} 

Mais dans mon test unitaire je reçois toujours un « L'objet de communication, System.ServiceModel.Channels.ServiceChannel, ne peut pas être utilisé pour la communication car il est dans le Faulted état "exception".

Est-il possible que le canal de rappel est toujours en défaut et si oui comment puis-je remplacer le canal de rappel?

+0

Pourriez-vous préciser ce que fait votre test unitaire lorsqu'il déclenche l'exception? –

+0

Dans mon test unitaire, je crée un hôte de service et une instance de client. J'inscris le client sur le service et ensuite j'arrête le service en mettant la référence à null. Après cela, j'attends 20 secondes (j'utilise une session fiable avec un InactivityTimeout de 10 secondes, donc je suis sûr que la connexion est perdue après 20 secondes) puis j'appelle la méthode DoSomething() sur le client. Maintenant, je recréer le service et attendre le client à se reconnecter. En ce moment, j'ai l'exception. – phatoni

Répondre

5

jusqu'à présent j'ai connu qu'une connexion WCF doit être recréée sur la faute - il ne semble pas être un moyen de le récupérer autrement. Quand une erreur survient, la méthode semble bien fonctionner, mais souvent elle se déclenche et nettoie la connexion WCF (en créant une nouvelle, etc.) alors que la requête actuelle est en cours - ce qui fait échouer - particulièrement vrai pour les délais. Un couple de suggestions: - Si le délai est lié, conservez la dernière fois qu'un appel a été passé et une constante contenant la valeur du délai d'expiration. Si la connexion WCF a été supprimée en raison de l'inactivité, supprimez-la et recréer avant vous envoyez la demande sur le fil. - L'autre chose, il semble que vous n'êtes pas Réaddition le gestionnaire de défaut, ce qui signifie va se traité la première faute, mais la deuxième fois les défauts, il tombera sur sans gestionnaire causer aucune nouvelle n'a été fixé.

Espérons que cela aide

0

Avez-vous essayé de réinitialiser le canal de communication en appelant mServiceClient.Abort dans le gestionnaire d'événements Faulted?

Edit:

Je vois que vous ne pas l'objet de réinitialiser mCallback dans votre code de récupération. Vous devrez peut-être l'affecter à une nouvelle instance.

+0

Merci pour votre aide. Oui, j'ai essayé cela avant, mais il n'a pas aidé tant parce que je suis un « L'objet de communication, System.ServiceModel.Channels.ServiceChannel, ne peut pas être utilisé pour la communication car il est dans l'état Aborted » exception au lieu de ce qui précède exception. – phatoni

Questions connexes