我该如何重新打开失败的WCF频道?

时间:2011-08-10 13:31:03

标签: .net wcf

我正在使用客户端代理对象来访问WCF频道。要访问任何服务方法,调用将包含在try-catch中以确保定义良好的行为。

但是,一旦频道因任何原因无法使用,我想重新打开它。这样做的正确方法是什么?我看到两个问题:

1。何时检查

  • 在访问方法中的try / catch之前
  • 通过频道的Faulted,Aborted等活动

2。如何进行重新开放

这让我很烦恼。如果我理解正确的情况,我必须分别处理每个可能的状态。此外,如果同时收到两个方法调用(仅适用于前一个点的选项A),我可能必须避免线程问题,例如打开通道两次。

我记得在重新开通频道时需要考虑很多事情。需要区分Faulted和Closed(和Closing),操作顺序很重要,某些操作使对象无效(?)。

好像这不够麻烦,MSDN显然提供了错误的示例代码(缺少案例,粗略处理边缘条件等),所以我根本不能依赖它。

2 个答案:

答案 0 :(得分:2)

频道无法重新开启。一旦通道处于Faulted状态,唯一有效的状态转换就是调用Abort。中止当前通道/代理后,您可以启动新通道/代理并建立与服务器的新连接。

答案 1 :(得分:0)

作为参考,这是我目前使用的:

class FooProxy : IFoo
{
    private readonly object _Sync = new object ();
    private IFoo Channel;

    public FooProxy ()
    {
    }

    private void CreateChannel ()
    {
        lock (_Sync) {
            if (Channel != null) {
                if (((ICommunicationObject) Channel).State == CommunicationState.Opened) {
                    return;
                }
            }

            // Attempt to create new connection
            var factory = new ChannelFactory<IFoo> (...);
            var channel = factory.CreateChannel ();

            ((ICommunicationObject) channel).Faulted += (s, e) => ((ICommunicationObject) Channel).Abort ();

            try {
                ((ICommunicationObject) channel).Open ();
            }
            catch (EndpointNotFoundException) {
                // dont worry
                return;
            }

            Channel = channel;
        }
    }

    public string DoStuff ()
    {
        // try to create a channel in case it's not there
        CreateChannel ();

        try {
            return Channel.DoStuff ();
        }
        // something goes wrong -> ensure well defined behavior
        catch (CommunicationException ex) {
            return null;
        }
    }
}