为什么即使Lifetime返回null,我的C#Remoting对象也会超时?

| 这是经过数天的谷歌搜索来找到我的问题的明确答案的最后手段。 我已经创建了Windows服务,Windows窗体和Remoting对象(全部在C#中)。我正在使用Remoting对象通过事件在服务和表单之间进行通信。 这是对象之间典型交互的简化示例: AdminForm调用RemoteObject的方法RequestLoadForm() RemoteObject触发AdminService正在监听的事件 通知AdminService事件,并在RemoteObject上调用LoadFormData(字符串数据) RemoteObject触发AdminForm正在监听的事件 AdminForm被通知该事件,并且可以使用字符串数据在AdminForm的控件上设置值 一切正常,在前5分钟左右的时间内,一切都能很好地交互。之后,对象之间的连接会以某种方式断开,并且我无法再在对象之间进行通信。 解决该问题的第一个尝试是覆盖InitializeLifetimeService方法以返回null。这没有帮助(尽管可以避免将来出现任何租赁问题)。 第二次尝试是使我的AdminForm和AdminService ISponsors成为RemoteObject,并设置它们以续订该对象上的租约。再一次,没有解决问题。 在各种Google搜索中,我发现有人提到事件处理程序被垃圾回收。我不确定这是否是问题,但我想我会提一下。 连接空闲超过5分钟后,会弹出此错误消息: 用户代码未处理System.Runtime.Remoting.RemotingException   消息= \“找不到请求的服务”   源= \“ System.Runtime.Remoting \” 现在,关于此的奇怪的事情是它发生在AdminService端。 AdminForm可以很好地调用RemoteObject上的方法。这会弹出事件,然后AdminService会看到此事件,并尝试调用RemoteObject的方法LoadFormData(string data),这是引发异常的地方。 由于我似乎找不到解决问题的方法,因此我对Google搜索完全感到精疲力尽。     
已邀请:
我面临着类似的问题。希望以下观察和解决方案也适用于有类似问题的任何人。 让对象A在整个应用程序域中与对象B通信,而对象B将通过一些事件处理程序回调给对象A。对象A和对象B均继承自MarshalByRefObject,以启用跨应用程序域的相互调用。 对象B覆盖InitializeLifeTimeService以为无限租期返回null。但是,该程序启动后,连接仍将过期约5分钟(恢复默认的初始租约时间)。 一个重要的观察结果是,对象A的调用仍将成功执行,但是当对象B回调时,对象B会引发异常。显然,对象A的回调代理发生了连接到期,反之则没有如我们所愿 因此,快速回答,请确保对象A和B都覆盖InitializeLifeTimeService以返回null。至少对于我来说,这将解决问题。 只是一些其他的东西,当连接过期时,这并不一定意味着已对连接的对象进行垃圾回收。租约到期将导致代理断开连接,但是实际的对象可能仍存在于相应的应用程序域中。如果您将被租用对象的租约到期期限保持不变,则可能会使您看不清整个图片。     
应该被覆盖:
public override object InitializeLifetimeService(){
  return null;
}
    
您可以在服务器端的System.Runtime.Remoting.Lifetime.LifetimeServices中设置的静态属性:
System.Runtime.Remoting.Lifetime.LifetimeServices.LeaseTime = TimeSpan.MaxValue;
但我更喜欢使用租赁/赞助商(在客户端) http://msdn.microsoft.com/en-us/library/6tkeax11.aspx
MarshalByRefObject obj = remotingObject as MarshalByRefObject;
ILease lease = (ILease)obj.GetLifetimeService();
MyClientSponsor sponsor = new MySponsor();
lease.Register(sponsor);
如果在编组过程中还有其他问题,请使用System.Runtime.Remoting.Services.TrackingServices命名空间 http://msdn.microsoft.com/zh-CN/library/system.runtime.remoting.services.trackingservices.aspx     
您应该覆盖方法InitializeLifeTimeService()而不是GetLifetimeService()以返回null。
 public object InitializeLifetimeService(){
   return null;
 }
然后,移除的对象应具有无限的使用寿命。     
这可能有几个原因。 您可能在错误的对象上覆盖
InitializeLifetimeService
。在源代码中搜索所有提及ѭ5的内容,并给每个人一个长而刻苦的外观。 无限租约仅持续到卸载应用程序域。在源代码中搜索所有有关ѭ6的内容,并给每一个卸载任何AppDomain的内容长而艰苦的外观。 AppDomain可能已经重新加载,并且进程终止,例如Win32服务重新启动。如果将服务器部署到某种类型的应用程序服务器中,并且某些部署操作或错误恢复触发了重新加载,则也可以由第三方代码卸载它。检查第三方日志以找到证据。 添加足够的日志记录,并仔细研究异常堆栈跟踪,以确保您没有调用第三方服务器对象(可能通过您自己的无限租约服务器对象),也不会调用已加载的旧版本代码谁知道在哪里,以便上面的源代码研究可能会错过它。 我刚刚完成了对事件的研究,结果发现该事件是列表中第一项和最后一项的组合。     

要回复问题请先登录注册