双工通道故障事件在第二次连接尝试时不会上升

时间:2012-06-01 09:38:04

标签: c# .net wcf wcf-4 duplex-channel

我有常规的net.tcp WCF服务客户端,以及常规的net.tcp duplex (即带有回调)WCF服务客户端。我已经实现了一些逻辑,以便在服务出现故障的情况下不断重新实现连接。

它们以完全相同的方式创建:

FooServiceClient Create()
{
    var client = new FooServiceClient(ChannelBinding);
    client.Faulted += this.FaultedHandler;
    client.Ping(); // An empty service function to make sure connection is OK
    return client;
}

BarServiceClient Create()
{
    var duplexClient = new BarServiceClient(new InstanceContext(this.barServiceCallback));
    duplexClient.Faulted += this.FaultedHandler;
    duplexClient.Ping(); // An empty service function to make sure connection is OK
    return duplexClient;
}

public class Watcher
{
public Watcher()
{
    this.CommunicationObject = this.Create();
}

ICommunicationObject CommunicationObject { get; private set; }

void FaultedHandler(object sender, EventArgs ea)
{
    this.CommunicationObject.Abort();
    this.CommunicationObject.Faulted -= this.FaultedHandler;
    this.CommunicationObject = this.Create();
}
}

FaultedHandler()使用上面的代码中止频道,重新创建

FooServiceClient重新连接逻辑正常工作,在多次故障后重新连接。然而,几乎相同但双工BarServiceClient仅从第一个BarServiceClient实例接收Faulted事件,即一次

为什么只有双工BarServiceClient的第一个实例出现故障?有没有解决方法?


类似的未回答的问题:WCF Reliable session without transport security will not faulted event on time

1 个答案:

答案 0 :(得分:1)

在对抗WCF的两天后,我找到了一个解决方法。

有时WCF会触发Faulted事件,但有时则不会。但是,Closed事件始终会被触发,尤其是在Abort()调用之后。

所以我在Abort()中致电FaultedHandler,有效地触发Closed事件。随后,ClosedHandler执行重新连接。如果框架永远不会触发Faulted,则始终会触发Closed事件。

BarServiceClient Create()
{
    var duplexClient = new BarServiceClient(new InstanceContext(this.barServiceCallback));
    duplexClient.Faulted += this.FaultedHandler;
    duplexClient.Closed += this.ClosedHandler;
    duplexClient.Ping(); // An empty service function to make sure connection is OK
    return duplexClient;
}

public class Watcher
{
public Watcher()
{
    this.CommunicationObject = this.Create();
}

ICommunicationObject CommunicationObject { get; private set; }

void FaultedHandler(object sender, EventArgs ea)
{
    this.CommunicationObject.Abort();
}

void ClosedHandler(object sender, EventArgs ea)
{
    this.CommunicationObject.Faulted -= this.FaultedHandler;
    this.CommunicationObject.Closed -= this.ClosedHandler;
    this.CommunicationObject = this.Create();
}
}