Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing threads in a service to wait for another thread to finish

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

like image 909
littlecharva Avatar asked Nov 18 '25 22:11

littlecharva


2 Answers

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.

like image 189
Marc Gravell Avatar answered Nov 21 '25 12:11

Marc Gravell


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 )
        {
             ...
        }
     }
     ...
}
like image 30
Blair Conrad Avatar answered Nov 21 '25 13:11

Blair Conrad