Дуплексный канал Неисправное событие не возникает при второй попытке подключения
У меня есть обычный сервисный клиент 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();
}
}