从客户端部署SingleCall对象时,Remoting通道调用两次Dispose方法

时间:2010-09-23 16:41:27

标签: c# remoting

我们在远程通道中发布了许多类作为singlecalls。该应用程序驻留在Windows服务中。它们用于以下场景:

  1. 来自同一个应用程序域
  2. 使用CrossAppDomain远程通道从另一个应用程序域
  3. 使用tcp频道从远程客户端通过网络
  4. 由于在这三种情况下使用了其中一些类,我们有一些常用的代码来对它们进行操作,例如:

    using(IRemoteObject remoteObject= (IRemoteObject) 
            RemotingHelper.GetObject(typeof(IRemoteObject)))
    {
       remoteObject.DoStuff();
    }
    

    RemotingHelper已经知道如何根据场景创建对象。这是对Ingo Rammer的修改。

    所有远程对象接口都继承自IDisposable,所有远程对象都继承自MarshalByRefObject。

    因此,在前两种情况下使用此代码的情况下,代码行为正确,但是当通过实际远程处理使用时,远程对象被创建两次并被处理两次。

    这是因为Dispose()调用(由使用语句创建的调用)作为新的远程调用进行管理,但远程处理的基础结构已经被调用到自动处理对象,因为它是SingleCall对象的行为方式:每次调用都会创建一个新实例并自动处理它。

    是否有任何配置值可以避免这些重复(冗余)呼叫?


    编辑:我已经知道为什么会这样。在远程SingleCall IDisposable对象的情况下,远程通道在方法返回后自动调用Dispose,第二个调用由客户端生成的代理完成,导致在服务器端实例化新对象,仅用于调用Dispose方法

    这第二个电话是我想要避免的,因为它是不需要的。

1 个答案:

答案 0 :(得分:1)

更多地考虑这个问题,我倾向于认为这是正确的行为。据我所知SingleCall,每次在对象上调用方法时,服务器都会创建一个新对象。因此,创建和处理多个对象是有意义的。也就是说,这段代码:

IRemoteObject remoteObject= (IRemoteObject) 
        RemotingHelper.GetObject(typeof(IRemoteObject));

为客户端上的对象创建代理。如果我没记错的话,没有与服务器联系。

现在,当你执行:

remoteObject.DoStuff();

进行远程通话。服务器创建一个对象,执行该方法,返回值(如果有的话),并处理该对象。

然后,当您调用Dispose(或using语句生成的代码时),服务器再次执行此操作:创建对象,调用Dispose方法并销毁对象。

这是SingleCall的工作方式:“当您将对象配置为SingleCall对象时,系统会为每个客户端方法调用创建一个新对象。” http://msdn.microsoft.com/en-us/library/aa719487(v=VS.71).aspx

为什么在您的方案1和2中没有发生这种情况有点令人困惑。

旧回应:

我不知道任何配置参数来防止这种行为。但是,如果您实现了Dispose方法as recommended,则应该有一个标志,指出该对象是否已被释放。因此,多次调用Dispose应该不是问题。