如何治愈故障的WCF频道?

时间:2010-01-05 19:00:59

标签: .net wcf faulted

当单个ClientBase<T>实例用于多个WCF服务调用时,它可以使某个通道进入故障状态(即,当服务关闭时)。

我想在服务再次启动时自动修复频道。我找到的唯一方法是在每次方法调用之前调用以下代码:

if (clientBase.InnerChannel.State == CommunicationState.Faulted)
{
      clientBase.Abort();
      ((IDisposable)clientBase).Dispose();
      clientBase = new SampleServiceClientBase();
}

我觉得这不是正确的做法。有人有更好的主意吗?

2 个答案:

答案 0 :(得分:19)

你做不到。一旦渠道出现故障,它就会出现故障。您必须创建一个新频道。 WCF通道是有状态的(以某种说法),因此故障通道意味着状态可能已损坏。

您可以做的是将您正在使用的逻辑放入实用程序方法中:

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

然后,您可以使用以下内容调用您的服务:

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

或者如果您想使用默认的无参数构造函数,只需:

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

由于它还处理服务为null的情况,因此在调用服务之前无需初始化服务。

我能提供的最好的东西。也许别人有更好的方法。

答案 1 :(得分:0)

这就是我目前正在做的事情,但我不能说这是最好的选择。

我在呼叫中捕获到异常时重新创建代理。

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