如果在remoting里,服务端要调用客户端的方法,则必须首先客户端要订阅服务端的事件,并把一个方法委托传给服务端。
但是有时客户端发生异常退出了,而服务端并不知道,那么这是服务端再调用客户端的方法委托,就会报错,然后就会退出。
下面的方法可以解决这个问题,首先获得服务端的调用委托链表,检查每一个,对于没有响应的就删除。
首先客户端要有方法供服务端调用,于是客户端必须实现接口,其中ServiceEventArg类是一个包含服务端事件信息的类:
//
客户端要实现的接口
public interface IClientEvent
... {
void handleEvent(object sender, ServiceEventArg e);
}
public interface IClientEvent
... {
void handleEvent(object sender, ServiceEventArg e);
}
服务端要有这个接口里的方法委托申明,这样才能调用:
//
服务端的委托申明,和客户端的接口中的方法一样
public delegate void ServiceEvent( object sender, ServiceEventArg e);
public delegate void ServiceEvent( object sender, ServiceEventArg e);
然后在服务端的远程对象中,加入这几个方法,分别用于订阅、取消订阅、和触发订阅到服务端的所有委托
//
服务端的远程对象
public class RemoteManager : System.MarshalByRefObject
... {
public static event ServiceEvent se;
//订阅到服务端
public void ConnectToServiceEvent(IClientEvent c)
...{
se += new ServiceEvent(c.handleEvent);
}
//取消订阅
public void DisConnectToServiceEvent(IClientEvent c)
...{
se -= new ServiceEvent(c.handleEvent);
}
//依次调用订阅的方法
public void fireEvent(object sender,ServiceEventArg e)
...{
if (se != null)
...{
Delegate[] target = se.GetInvocationList();
foreach (ServiceEvent client in target)
...{
try
...{
client(sender, e);
}
catch
...{
se -= client;
}
}
}
}
}
public class RemoteManager : System.MarshalByRefObject
... {
public static event ServiceEvent se;
//订阅到服务端
public void ConnectToServiceEvent(IClientEvent c)
...{
se += new ServiceEvent(c.handleEvent);
}
//取消订阅
public void DisConnectToServiceEvent(IClientEvent c)
...{
se -= new ServiceEvent(c.handleEvent);
}
//依次调用订阅的方法
public void fireEvent(object sender,ServiceEventArg e)
...{
if (se != null)
...{
Delegate[] target = se.GetInvocationList();
foreach (ServiceEvent client in target)
...{
try
...{
client(sender, e);
}
catch
...{
se -= client;
}
}
}
}
}
此外,ServiceEventArg这个类由于要从服务端传到客户端,所以这个类必须标记为 [Serialible]。