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

Posted

技术标签:

【中文标题】我应该如何重新打开失败的 WCF 频道?【英文标题】:How should I reopen a failed WCF channel? 【发布时间】:2011-08-10 13:31:02 【问题描述】:

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

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

1.何时检查

就在访问方法中的 try/catch 之前 通过通道的Faulted、Aborted等事件

2。如何执行重新打开

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

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

似乎这还不够麻烦,MSDN 显然提供了错误的示例代码(缺少案例、草率地处理边缘条件等),所以我根本不能依赖它。

【问题讨论】:

【参考方案1】:

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

【讨论】:

不确定您是否一直阅读他的问题。只有一个他想考虑的案例是错误的。您将如何处理其他情况? @Lucas:任何其他情况都是一样的 - 无法重新打开频道。一旦通道发生故障、关闭或关闭,它就消失了。【参考方案2】:

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

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;
        
    

【讨论】:

以上是关于我应该如何重新打开失败的 WCF 频道?的主要内容,如果未能解决你的问题,请参考以下文章

WCF 回调通道出现故障

Wcf 回调网络 tcp 双工仅 1 路故障

无法连接到远程服务器 wcf服务

如何在C#中的for循环中使用WCF客户端

使用 Laravel Echo 加入频道时,如何判断身份验证失败?

YouTube API:如何使用标签 Y 从频道 X 获取视频?