当单个ClientBase<T>
实例用于多个WCF服务调用时,它可以使某个通道进入故障状态(即,当服务关闭时)。
我想在服务再次启动时自动修复频道。我找到的唯一方法是在每次方法调用之前调用以下代码:
if (clientBase.InnerChannel.State == CommunicationState.Faulted)
{
clientBase.Abort();
((IDisposable)clientBase).Dispose();
clientBase = new SampleServiceClientBase();
}
我觉得这不是正确的做法。有人有更好的主意吗?
答案 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();
}