2

通常の net.tcp WCF サービス クライアントと、通常の net.tcpデュプレックス(コールバック付き) 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だけ Faulted イベントを受け取ります。BarServiceClient

duplex の最初のインスタンスだけBarServiceClientが faulted イベントを取得するのはなぜですか? 回避策はありますか?


同様の未回答の質問:トランスポート セキュリティのない WCF の信頼できるセッションでは、時間どおりにイベントが発生しません。

4

1 に答える 1

1

WCF との戦いで 2 日間過ごした後、回避策を見つけました。

WCF がFaultedイベントを発生させる場合もありますが、そうでない場合もあります。ただし、Closed特に呼び出しの後、イベントは常に発生しAbort()ます。

そのため、効果的にイベントを発生Abort()させるものを呼び出します。その後、は再接続を実行します。whenがフレームワークによって決して発生しない場合、イベントは常に発生します。FaultedHandlerClosedClosedHandlerFaultedClosed

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();
}
}
于 2012-06-01T14:48:30.213 に答える