How to heal faulted WCF channels?

后端 未结 2 1698
别那么骄傲
别那么骄傲 2020-12-09 19:09

When a single ClientBase instance is used for multiple WCF service calls, it can get a channel into a faulted state (ie. when the service is down).

相关标签:
2条回答
  • 2020-12-09 19:46

    This is what I'm currently doing, but I can't say this is the best option either.

    I recreate the proxy when an exception is caught on the call.

    try
    {
        ListCurrentProcesses();
    }
    catch (TypeLoadException ex)
    {
        Debug.Print("Oops: " + ex.Message);
        m_Proxy = new ProcessManagerProxy();
    }
    catch (EndpointNotFoundException endpointEX)
    {
        Debug.Print("Oops: " + endpointEX.Message);
        m_Proxy = new ProcessManagerProxy();
    }
    catch (CommunicationException communicationEx)
    {
        Debug.Print("Oops: " + communicationEx.Message);
        m_Proxy = new ProcessManagerProxy();
    }
    
    0 讨论(0)
  • 2020-12-09 19:57

    You can't. Once a channel is faulted, it's faulted for good. You must create a new channel. WCF channels are stateful (in a manner of speaking), so a faulted channel means the state may be corrupted.

    What you can do is put the logic you're using into a utility method:

    public static class Service<T> where T : class, ICommunicationObject, new()
    {
        public static void AutoRepair(ref T co)
        {
            AutoRepair(ref co, () => new T());
        }
    
        public static void AutoRepair(ref T co, Func<T> createMethod)
        {
            if ((co != null) && (co.State == CommunicationState.Faulted))
            {
                co.Abort();
                co = null;
            }
            if (co == null)
            {
                co = createMethod();
            }
        }
    }
    

    Then you can invoke your service with the following:

    Service<SampleServiceClient>.AutoRepair(ref service,
        () => new SampleServiceClient(someParameter));
    service.SomeMethod();
    

    Or if you want to use the default parameterless constructor, just:

    Service<SampleServiceClient>.AutoRepair(ref service);
    service.SomeMethod();
    

    Since it also handles the case where the service is null, you don't need to initialize the service before calling it.

    Pretty much the best I can offer. Maybe somebody else has a better way.

    0 讨论(0)
提交回复
热议问题