从客户端处置 SingleCall 对象时,远程通道调用两次 Dispose 方法
我们在远程通道中以单一调用的形式发布了许多类。该应用程序驻留在 Windows 服务中。它们在以下场景中使用:
- 来自同一应用程序域
- 使用 CrossAppDomain 远程处理通道的另一个应用程序域
- 使用 tcp 通道通过网络从远程客户端
由于其中一些类在这三种情况下使用,我们有一些通用代码对它们进行操作,例如:
using(IRemoteObject remoteObject= (IRemoteObject)
RemotingHelper.GetObject(typeof(IRemoteObject)))
{
remoteObject.DoStuff();
}
RemotingHelper 已经知道如何根据场景创建对象。它是 Ingo Rammer 的改进型。
所有远程对象接口均继承自 IDisposable,所有远程对象均继承自 MarshalByRefObject。
因此,在前两种情况下使用此代码时,代码行为正确,但当通过真正的远程处理使用时,远程对象会创建两次并处置两次。
发生这种情况是因为 Dispose() 调用(由 using 语句进行的调用)作为新的远程调用进行管理,但远程处理基础结构已经自动调用对象的处置,因为这就是如何处理对象的方法。它的行为适用于 SingleCall 对象:每次调用都会创建一个新实例并自动释放它。
是否有任何配置值可以避免这些重复(冗余)调用?
编辑:我已经知道为什么会发生这种情况。对于远程 SingleCall IDisposable 对象,远程通道在方法返回后自动调用 Dispose,第二次调用由客户端生成的代理完成,导致在服务器端实例化一个新对象,仅用于调用 Dispose方法。
我想避免第二次调用,因为它是不必要的。
We have many classes published in a remoting channel as singlecalls. The application resides into a windows service. They are being used in the following scenarios:
- From the same application domain
- From another application domain using CrossAppDomain remoting channel
- From a remote client through the network using a tcp channel
As some of these classes are used in the three cases we have some common code to do operations with them, something like:
using(IRemoteObject remoteObject= (IRemoteObject)
RemotingHelper.GetObject(typeof(IRemoteObject)))
{
remoteObject.DoStuff();
}
The RemotingHelper already knows how to create the objects depending on the scenario. It is a modification of the Ingo Rammer's one.
All the remote object interfaces inherit from IDisposable, and all remote objects inherit from MarshalByRefObject.
So, in the case of using this code in the first two cases, the code behaves correctly, but when used through real remoting the remote object is created twice and disposed twice.
This happens because the Dispose() call, the one being made by the using statement, is managed as a new remote call, but the remoting infraestructure already called to the dispose of the object automatically, because that's how it behaves for SingleCall objects: each call creates a new instance and disposes it automatically.
Is there any configuration value to avoid these repeated (redundant) calls?
Edit: I already knew why this happened. In the case of a remote SingleCall IDisposable object the remoting channel automatically calls to Dispose after the Method returns, the second call is done by the proxy generated at client side, causing a instantiation of a new object at server side, just for calling the Dispose method.
This second call is the one I want to avoid because it is unneeded.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
进一步思考这一点,我倾向于认为这是正确的行为。据我了解
SingleCall
,每次调用对象上的方法时,服务器都会创建一个新对象。因此创建和处置多个对象是有意义的。也就是说,此代码:为客户端上的对象创建代理。如果我没记错的话,没有与服务器进行任何联系。
现在,当您执行:
remoteObject.DoStuff();
就会进行远程调用。服务器创建一个对象,执行该方法,返回值(如果有),然后处理该对象。
然后,当您调用
Dispose
(或由using
语句生成的代码执行此操作)时,服务器会再次执行此操作:创建一个对象,调用Dispose 方法,并销毁该对象。
这是
SingleCall
的工作方式:“当您将对象配置为 SingleCall 对象时,系统会为每个客户端方法调用创建一个新对象。” http://msdn.microsoft.com/en -us/library/aa719487(v=VS.71).aspx不过,为什么在场景 1 和 2 中没有发生这种情况有点令人困惑。
旧响应:
我不知道有任何配置参数可以防止这种行为。但是,如果您实现了
Dispose
方法 按照建议,您应该有一个标志来表明该对象是否已被处置。因此多次调用Dispose
应该不是问题。Thinking more about this, I'm inclined to think that this is correct behavior. As I understand
SingleCall
, each time you call a method on the object, the server creates a new object. So it makes sense that multiple objects are created and disposed. That is, this code:Creates a proxy for the object on the client. If I recall correctly, no contact is made with the server.
Now, when you execute:
remoteObject.DoStuff();
A remote call is made. The server creates an object, executes the method, returns values (if any), and disposes of the object.
Then, when your call
Dispose
(or the code generated by theusing
statement does), the server does it again: create an object, calls theDispose
method, and destroys the object.This is the way
SingleCall
works: "When you configure an object to be a SingleCall object, the system creates a new object for each client method invocation." http://msdn.microsoft.com/en-us/library/aa719487(v=VS.71).aspxWhy that doesn't happen in your scenarios 1 and 2 is a bit confusing, though.
OLD RESPONSE:
I don't know of any configuration parameter to prevent that behavior. However, if you implemented the
Dispose
method as recommended, you should have a flag that says whether the object has already been disposed. So callingDispose
multiple times shouldn't be an issue.