Как лечить неисправные каналы WCF?
Когда один ClientBase<T>
Экземпляр используется для нескольких вызовов службы WCF, он может перевести канал в неисправное состояние (т. е. когда служба не работает).
Я хотел бы вылечить канал автоматически, когда сервис снова заработает. Единственный найденный способ - вызывать следующий код перед каждым вызовом метода:
if (clientBase.InnerChannel.State == CommunicationState.Faulted)
{
clientBase.Abort();
((IDisposable)clientBase).Dispose();
clientBase = new SampleServiceClientBase();
}
У меня ощущение, что это не правильный способ сделать это. У кого-нибудь есть идея получше?
2 ответа
Ты не можешь Как только канал неисправен, он неисправен навсегда. Вы должны создать новый канал. Каналы WCF имеют состояние (в некотором смысле), поэтому неисправный канал означает, что состояние может быть повреждено.
То, что вы можете сделать, это поместить логику, которую вы используете, в служебный метод:
public static class Service<T> where T : class, ICommunicationObject, new()
{
public static void AutoRepair(ref T co)
{
AutoRepair(ref co, () => new T());
}
public static void AutoRepair(ref T co, Func<T> createMethod)
{
if ((co != null) && (co.State == CommunicationState.Faulted))
{
co.Abort();
co = null;
}
if (co == null)
{
co = createMethod();
}
}
}
Затем вы можете вызвать свой сервис с помощью следующего:
Service<SampleServiceClient>.AutoRepair(ref service,
() => new SampleServiceClient(someParameter));
service.SomeMethod();
Или, если вы хотите использовать конструктор по умолчанию без параметров, просто:
Service<SampleServiceClient>.AutoRepair(ref service);
service.SomeMethod();
Так как он также обрабатывает случай, когда услуга null
Вам не нужно инициализировать службу перед вызовом.
Практически лучшее, что я могу предложить. Может быть, у кого-то есть лучший способ.
Это то, чем я сейчас занимаюсь, но не могу сказать, что это лучший вариант.
Я воссоздаю прокси, когда исключение ловится на вызове.
try
{
ListCurrentProcesses();
}
catch (TypeLoadException ex)
{
Debug.Print("Oops: " + ex.Message);
m_Proxy = new ProcessManagerProxy();
}
catch (EndpointNotFoundException endpointEX)
{
Debug.Print("Oops: " + endpointEX.Message);
m_Proxy = new ProcessManagerProxy();
}
catch (CommunicationException communicationEx)
{
Debug.Print("Oops: " + communicationEx.Message);
m_Proxy = new ProcessManagerProxy();
}