当WCF通道处于故障状态时,我正试图找到一种优雅的方法来重试操作。我已尝试使用Policy Injection AB重新连接并在第一次调用时发生故障状态异常时重试该操作,但PolicyInjection.Wrap方法似乎不喜欢包装TransparentProxy对象(从ChannelFactory.CreateChannel返回的代理)。
我是否可以尝试其他任何机制,或者我如何尝试让PIAB解决方案正常工作 - 任何链接,示例等都将不胜感激。
以下是我使用的失败代码:
var channelFactory = new ChannelFactory(endpointConfigurationName);
var proxy = channelFactory.CreateChannel(...);
proxy = PolicyInjection.Wrap<IService>(proxy);
谢谢。
答案 0 :(得分:3)
我宁愿使用回调函数,如下所示:
private SomeServiceClient proxy;
//This method invokes a service method and recreates the proxy if it's in a faulted state
private void TryInvoke(Action<SomeServiceClient> action)
{
try
{
action(this.proxy);
}
catch (FaultException fe)
{
if (proxy.State == CommunicationState.Faulted)
{
this.proxy.Abort();
this.proxy = new SomeServiceClient();
//Probably, there is a better way than recursion
TryInvoke(action);
}
}
}
//Any real method
private void Connect(Action<UserModel> callback)
{
TryInvoke(sc => callback(sc.Connect()));
}
在您的代码中,您应该致电
ServiceProxy.Instance.Connect(user => MessageBox.Show(user.Name));
而不是
var user = ServiceProxy.Instance.Connect();
MessageBox.Show(user.Name);
虽然我的代码使用代理类方法,但您可以使用Channels编写类似的代码。
答案 1 :(得分:0)
非常感谢您的回复。我最终做的是创建一个装饰器类型类,它实现了我的服务接口,然后只包装了ChannelFactory生成的透明代理。然后,我可以使用策略注入应用程序块在此之上创建一个层,该层将代码注入到将尝试操作的每个操作调用中,如果发生CommunicationObjectFaultedException,将中止该通道,重新创建它并重试该操作。它现在工作得很好 - 尽管它工作得很好,但唯一的缺点是提到的包装类必须实现每个服务操作,但这是我可以使用PIAB的唯一方法,因为这对我来说是有意义的,以防我找到了将来,只需使用界面就可以轻松改变。