tags:

views:

45

answers:

1

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:

  1. From the same application domain
  2. From another application domain using CrossAppDomain remoting channel
  3. 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.

A: 

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:

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

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 the using statement does), the server does it again: create an object, calls the Dispose 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).aspx

Why 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 calling Dispose multiple times shouldn't be an issue.

Jim Mischel
It is an issue, because it is a remote object, so a remote call is done. What I want is to avoid these extra remote calls over the wire The Dispose in this case is called to two different instances, the first time is the remoting channel that disposes the object, then a new instance is created for calling to the Dispose method because the client did call to the method through the proxy.
jmservera
Yes, I know this is the way SingleCall works. In scenarios 1 and 2 it does not happen because for 1 we use direct instantiation (no remoting involved) and for 2 we use cross-appdomain (AppDomain.CreateInstanceFromAndUnwrap) that it uses remoting, but you have to call to Dispose yourself. In the 3rd case the remoting channel is automatically calling dispose when the method call returns. I want to avoid that the proxy at client side calls to the remote object for disposal, because it is an unneeded call. It does not break anything, it's only superflous.
jmservera
So what you want is for the client proxy object to say, "He's calling Dispose, but I know that's not necessary so I'll just not call it." I doubt very seriously that there's any kind of configuration option to specify that behavior.
Jim Mischel