2

我试图找到一种优雅的方式来在 WCF 通道处于故障状态时重试操作。我尝试使用 Policy Injection AB 重新连接并在第一次调用时发生故障状态异常时重试操作,但 PolicyInjection.Wrap 方法似乎不喜欢包装透明代理对象(从 ChannelFactory.CreateChannel 返回的代理)。

是否有任何其他机制我可以尝试或者我如何尝试让 PIAB 解决方案正常工作 - 任何链接、示例等将不胜感激。

这是我使用的失败的代码:
var channelFactory = new ChannelFactory(endpointConfigurationName);
var proxy = channelFactory.CreateChannel(...);
proxy = PolicyInjection.Wrap<IService>(proxy);

谢谢你。

4

2 回答 2

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 编写类似的代码。

于 2010-11-23T10:04:01.020 回答
0

非常感谢你的回复。我最终做的是创建一个装饰器类型类来实现我的服务接口,然后它只是包装了由 ChannelFactory 生成的透明代理。然后我可以使用策略注入应用程序块在此之上创建一个层,该层将代码注入每个尝试操作的操作调用,如果发生 CommunicationObjectFaultedException,将中止通道,重新创建并重试操作. 它现在工作得很好——虽然它工作得很好,但唯一的缺点是提到的包装类必须实现每个服务操作,但这是我可以使用 PIAB 的唯一方法,因为这对我来说很有意义,以防万一我找到了将来,只需使用接口即可轻松更改。

于 2010-12-11T04:26:47.383 回答