【问题标题】:Sponsor's Renewal function stops being called赞助商的续订功能停止被调用
【发布时间】:2013-09-22 11:11:50
【问题描述】:

我有一个服务器和客户端进程都在同一台机器上运行。客户端创建一个 CAO 对象并使用它一段时间(

我将 InitialLeaseTime 和 RenewOnCallTime 设置为 10s(0.1s 和 15s 有同样的问题)。我可以看到有几分钟,赞助商的 Renweal 函数每 10 秒被调用一次。几分钟后,客户开始做不同类型的工作,并且停止调用赞助商(这似乎是错误的)。几分钟后,当客户端尝试使用远程对象时,它会抛出一个异常,说它已断开连接(可能是因为很长时间没有调用赞助商)。

租约经理似乎在一段时间后停止尝试检查租约。

【问题讨论】:

    标签: vb.net ipc remoting


    【解决方案1】:

    回复之间的时间很长,但我认为其他人也可能遇到这个问题,所以就这样吧。

    我建议在 VS 中附加到您的服务器,转到“调试”菜单,选择“异常”,然后检查“System.Net.Sockets.SocketException”异常。这将在发生任何套接字异常时中断您的程序。

    就我而言,我最近开始看到这个问题,经过大量调试后发现,就在租赁管理器停止检查租约之前,发生了 SocketException。在我的例子中,套接字异常是AddressChangedCallback,带有堆栈跟踪:

    1      [External Code]
     2      System.dll!System.Net.Dns.TryGetAddrInfo(string name = "me.win.mycompany.com", System.Net.AddressInfoHints flags, out System.Net.IPHostEntry hostinfo = null)
     3      System.dll!System.Net.Dns.GetAddrInfo(string name)
     4      System.dll!System.Net.Dns.InternalGetHostByName(string hostName, bool includeIPv6)
     5      System.dll!System.Net.Dns.GetHostEntry(string hostNameOrAddress)
     6      System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.CoreChannel.UpdateCachedIPAddresses()
     7      System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.CoreChannel.OnNetworkAddressChanged(object sender = null, System.EventArgs e = {System.EventArgs})
     8      mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     9      mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     10     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
     11     System.dll!System.Net.NetworkInformation.NetworkChange.AddressChangeListener.AddressChangedCallback(object stateObject, bool signaled)
     12     mscorlib.dll!System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(object state, bool timedOut)
     13     [External Code]
    

    这个AddressChangedCallback, 在我的情况下似乎与网络适配器出现故障或被更改有关(您可以通过按住windows+r 然后输入ncpa.cpl 来查看您的网络适配器 - 如果您有两个或更多此事件可能是由您在它们之间切换引起的)似乎导致套接字停止读取。这意味着下次 LeaseManager 使用远程连接来检查远程租约时,它无法从死套接字中读取该租约。因此,它做了合理的事情——断开该赞助商,因为我们无法再阅读它,并将其从对象的赞助商列表中删除。由于它可能是相关对象的唯一赞助商,因此该对象随后会被 LeaseManger 取消赞助,让 GC 最终获得它。

    解决此问题的一种方法是,在您的 InitializeLifetimeService() 方法中,返回 null 而不是设置超时。这绕过了 LeaseManager,因此您不必担心对象会因为套接字异常而被取消赞助,因为您一开始就没有使用租约。但是,如果您像我一样,这也意味着您可能会在一段时间内在服务器上积累对象和非托管资源。我能看到的解决构建问题的唯一方法是让您的远程处理对象实现Dispose,并确保在完成后处理它。基本上,您不能依赖 LeaseManager 处理垃圾收集,因此您必须自己进行 GC,这是老式的方式。

    同样值得注意ITrackingHandler 对象将允许您跟踪与 LeaseManager 相关的对象何时断开连接、编组和取消编组。这对弄清楚发生了什么很有帮助,因为我可以看到一个对象正在断开连接,而不是从调用停止发生的事实中推断出来。

    【讨论】:

      【解决方案2】:

      我通过将赞助商放在服务器而不是客户端上来解决这个问题。服务器端赞助商似乎被可靠地调用到足以使远程对象保持活动状态。

      Class SelfSponsor
          Implements ISponsor
          Public Function Renewal(ByVal lease As ILease) As System.TimeSpan Implements ISponsor.Renewal
              Return lease.RenewOnCallTime
          End Function
      End Class
      

      并且在 MarshalByRef 远程对象的类中:

      Private Sponsor As SelfSponsor
      
      Public Sub SponsorYourself()
          Sponsor = New SelfSponsor
          DirectCast(GetLifetimeService(), ILease).Register(Sponsor)
      End Sub
      
      Public Sub UnSponsorYourself()
          DirectCast(GetLifetimeService(), ILease).Unregister(Sponsor)
      End Sub
      

      如果将 SponsorYourself() 代码放在构造函数中,则不知何故会引发异常,因此客户端会在创建对象后立即调用 SponsorYourself。

      如果服务器一直在运行并且客户端来来去去,这将是一个糟糕的解决方案,因为如果客户端在没有显式调用 UnsponsorYourself() 的情况下异常退出,那么该对象将永远保持活动状态。但在我的情况下,服务器是由客户端启动和停止的,所以这并不重要。

      【讨论】:

        猜你喜欢
        • 2020-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        相关资源
        最近更新 更多