1

Up until this point all the .NET remoting code I have written or worked with has been exposed as SingleCall.

I ran across a .NET remoting component hosted in a Windows service that is exposed as a Singleton.

This object has the potential to be called by more than one client at the same time, and it has no locks or other provisions to protect its internal state.

If I understand Singleton correctly then this has the potential for big problems correct?

Oli4
  • 489
  • 1
  • 9
  • 22
TWA
  • 12,756
  • 13
  • 56
  • 92
  • "no locks or other provisions to protect its internal state" ... are you sure it's a Singleton then? It's my understanding that you would need to have a lock to restrict (initial) construction to a single thread. – Dan Esparza Sep 16 '09 at 19:50

2 Answers2

8

No more potential than a SingleCall component. Both will have problems if they attempt to access a shared memory location in an unsafe manner.

The difference between SingleCall and Singleton is that, for SingleCall , every incoming request will get a new instance of the defined type created to handle that call. Each instance will have its own memory space and instance variables, but they can still share static and global variables, external resources, files, network connections, etc. If the SingleCall class is coded to access any shared memory state in a thread-unsafe manner, then you will have issues.

A Singleton, on the other hand, only gets one instance created for ALL incoming requests, so by definition, every instance variable in use within that singleton is, in fact, shared among all incoming requests. A good example might be a message publisher, that all code in the server needs to access to send messages to one or more subscribed clients....

To address comment from @Cocowalla, make sure if you do this you override the method

  MarshalByRefObject.InitializeLifetimeService() 

as shown, or your singleton will die out unexpectedly if no one calls it for a while...

public class MessageManager : MarshalByRefObject
{
    #region Singleton / MarshalByRefObject code        
    private static MessageManager mgr = 
        new MessageManager(); // creates singleton 
    static MessageManager() { }
    private MessageManager() { }
    public static MessageManager Instance { get { return mgr;  } }
    public override object InitializeLifetimeService() { return (null); }
    #endregion Singlelton code
    // ... other stuff ... 
 }

  // in Remoting Host initialization code...      
   MessageManager mgr = MessageManager.Instance; // generates singleton;
   RemotingServices.Marshal(mgr, URI);
lbras
  • 70
  • 2
  • 8
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • You will need to be wary of a Singleton's lifetime though - depending on your configuration, your Singleton that you expect to be around while the app is running can actually be automatically destroyed and recreated. In remoting, Singletons have a given 'lease' or 'lifetime', after which they will automatically be destroyed. It is possible to change the lifetime, or indeed to extend it indefinitely, but it's something to be aware of. Some more reading: http://www.thinktecture.com/resourcearchive/net-remoting-faq/singletonisdying http://msdn.microsoft.com/en-us/magazine/cc300474.aspx – Cocowalla Sep 16 '09 at 19:26
2

Yes. If the callers alter the object's internal state, and those methods are not thread-safe, then you're bound to get into trouble. That server should be single-call.

But as Charles points out, if the server object accesses shared resources (and what useful server doesn't?), even single-call servers can get into trouble. Still, those problems are more manageable. Access to a database, for example, can quite easily be made transactional, and hence safe.

Bottom line: going for single-call is a simple and effective way of getting rid of 'half' your troubles. Stick to it.

Tor Haugen
  • 19,509
  • 9
  • 45
  • 63