我有一个类似的环境(没有动态服务),并且当客户端通道出现故障时遇到了非常类似的问题。我想出的第一个解决方案是将回调包装在 try/catch 语句中,并在出现问题时删除有问题的客户端,但这有问题,而且看起来根本无法扩展。
我最终采用的解决方案是使用委托事件处理程序并使用 BeginInvoke 调用它。如果您还没有看过CodeProject:WCF/WPF 聊天应用程序 (Chatters) http://www.codeproject.com/KB/WCF/WCFWPFChat.aspx解决方案,我建议检查一下。
当用户登录时,将创建一个事件处理程序并将其添加到主事件中:
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 聊天应用程序(稍作修改)萨莎·巴伯 http://www.codeproject.com/script/Membership/Profiles.aspx?mid=569009.