Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何重新打开失败的WCF频道?_.net_Wcf - Fatal编程技术网

.net 如何重新打开失败的WCF频道?

.net 如何重新打开失败的WCF频道?,.net,wcf,.net,Wcf,我正在使用客户端代理对象访问WCF通道。要访问任何服务方法,调用将包装在try-catch中,以确保定义良好的行为 但是,一旦该频道因任何原因无法正常工作,我将重新打开它。正确的方法是什么?我看到两个问题: 1。何时检查 就在访问方法中的try/catch之前 通过通道的故障、中止等事件 2。如何执行重新打开操作 这让我很不安。如果我正确理解情况,我就必须分别处理每一种可能的状态。此外,我可能必须避免线程问题,例如,如果同时接收到两个方法调用,则打开通道两次(仅适用于前一点的选项A) 我记得

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

但是,一旦该频道因任何原因无法正常工作,我将重新打开它。正确的方法是什么?我看到两个问题:

1。何时检查

  • 就在访问方法中的try/catch之前
  • 通过通道的故障、中止等事件
2。如何执行重新打开操作

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

我记得在重开一个频道时有很多事情要考虑。需要区分故障和关闭(以及关闭),操作顺序很重要,某些操作会使对象无效(?)


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

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

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

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;
        }
    }
}
class-FooProxy:IFoo
{
私有只读对象_Sync=新对象();
专用IFoo频道;
公共代理()
{
}
私有void CreateChannel()
{
锁定(同步){
如果(通道!=null){
if(((ICommunicationObject)通道).State==通信状态.Opened){
返回;
}
}
//尝试创建新连接
var工厂=新渠道工厂(…);
var channel=factory.CreateChannel();
((ICommunicationObject)通道)。出现故障+=(s,e)=>((ICommunicationObject)通道)。中止();
试一试{
((ICommunicationObject)通道);
}
捕获(EndpointNotFoundException){
//别担心
返回;
}
通道=通道;
}
}
公共字符串DoStuff()
{
//尝试创建一个频道,以防它不在那里
CreateChannel();
试一试{
返回Channel.DoStuff();
}
//出现问题->确保定义良好的行为
捕获(通信例外){
返回null;
}
}
}

不确定你是否通读了他的问题。他想考虑的只有一个案例是错误的。你会如何处理其他案件?@Lucas:任何其他案件都是一样的-频道不能重新打开。一旦通道出现故障、关闭或关闭,它就会消失。