views:

855

answers:

5

I'm writing a service that has five different methods that can take between 5 seconds and 5 minutes to run.

The service will schedule these different methods to run at different intervals.

I don't want any of the methods to run concurrently, so how do I have the methods check to see if another method is running and queue itself to run when it finishes?

Anthony

+1  A: 

If you are using java, you can make the methods synchronized, which will prevent more than one thread from accessing it simultaneously.

trex279
A: 

Sorry, I forgot to actually say that I'm using C#.

littlecharva
+4  A: 

There's the MethodImplOptions.Synchronized attribute, as noted in the article Synchronized method access in C#, but that can lead to deadlocks as noted at MSDN. It sounds like, for your usage, this won't be a big concern.

Otherwise, the simplest approach would be to use the lock statement to make sure that only one method is executing at a time:

class ServiceClass
{
     private object thisLock = new object();

     public Method1()
     {
        lock ( thisLock )
        {
             ...
        }
     }

     public Method2()
     {
        lock ( thisLock )
        {
             ...
        }
     }
     ...
}
Blair Conrad
Deadlock is just as much an issue with a private lock as it is with [MethodImpl] - it is just a little harder to know which code might be accessing the lock.
Marc Gravell
+5  A: 

If you want simple, and all the methods are in the same class, ou can just use [MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void Foo() {...}

[MethodImpl(MethodImplOptions.Synchronized)]
public void Bar() {...}

For instance methods, this locks on this; for static methods, this locks on typeof(TheClass).

As such, these lock objects are public - so there is a remote (but genuine) chance that another bit of code might be locking on them. It is generally considered better practice to create your own lock object:

private readonly object syncLock = new object(); // or static if needed

...
public void Foo() {
   lock(syncLock) {
      ...
   }
}

etc


Aside: a curious fact; the ECMA spec doesn't define a specific pattern for [MethodImpl], even including an example of a private lock, as "valid". The MS spec, however, insists on this/typeof.

Marc Gravell
A: 

In general, I strongly discourage using the MethodImpl(MethodImplOptions.Synchronized) attribute to do thread synchronization. If you are going to do multi-threaded programming you really should think very carefully about exactly where and how you should be locking.

I may be exaggerating a bit but I find too many similarities between the MethodImpl synchronization method and others such as the use of the End statement in VB. It often signals to me that you don't really know what you are doing and hope that this statement/method/attribute will magically solve your problem.

Stephen Martin