Дуплексный канал Неисправное событие не возникает при второй попытке подключения

У меня есть обычный сервисный клиент WCF для net.tcp и обычный дуплексный сервис net.tcp (т.е. с обратным вызовом). Я реализовал некоторую логику, чтобы постоянно восстанавливать соединение в случае сбоя службы.

Они созданы точно так же:

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 получает событие Failed только с первого BarServiceClient экземпляр, то есть один раз.

Почему только первый экземпляр дуплекса BarServiceClient получает ошибочное событие? Есть ли обходные пути?


Похожий вопрос без ответа: надежный сеанс WCF без безопасности транспорта не повредит событию вовремя

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();
}
}
Другие вопросы по тегам