У меня похожая среда (без динамических сервисов), и у меня возникла очень похожая проблема при сбое клиентских каналов. Первое решение, которое я придумал, заключалось в том, чтобы обернуть обратные вызовы в операторах try / catch и удалить нарушающий работу клиент, если что-то пошло не так, но это имело проблемы и не выглядело так, как будто оно вообще масштабировалось.
Решение, которое я в итоге выбрал, состояло в том, чтобы использовать делегированный обработчик событий и вызывать его с помощью BeginInvoke. Если вы еще не посмотрели на решение CodeProject: приложение для чата WCF / WPF (Chatters) , я рекомендую проверить его.
Когда пользователь входит в систему, создается обработчик событий и добавляется к основному событию:
public bool Login()
{
...
_myEventHandler = new ChatEventHandler(MyEventHandler);
ChatEvent += _myEventHandler;
...
}
Когда сообщение необходимо передать, обработчики событий вызываются асинхронно:
private void BroadcastMessage(ChatEventArgs e)
{
ChatEventHandler temp = ChatEvent;
if (temp != null)
{
foreach (ChatEventHandler handler in temp.GetInvocationList())
{
handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
}
}
}
Когда возвращаются результаты, результат обрабатывается, и если что-то плохое происходит, обработчик событий для этого канала удаляется:
private void EndAsync(IAsyncResult ar)
{
ChatEventHandler d = null;
try
{
//get the standard System.Runtime.Remoting.Messaging.AsyncResult,and then
//cast it to the correct delegate type, and do an end invoke
System.Runtime.Remoting.Messaging.AsyncResult asres = (System.Runtime.Remoting.Messaging.AsyncResult)ar;
d = ((ChatEventHandler)asres.AsyncDelegate);
d.EndInvoke(ar);
}
catch(Exception ex)
{
ChatEvent -= d;
}
}
Приведенный выше код изменен (немного) из приложения для чата WCF / WPF, опубликованного Sacha Barber .