Avoid starting new thread with lock

lock
lock c# best practices
c# lock alternative
c# lock vs mutex
c# lock example
c# lock await
c# lock static object
c# lock vs monitor

Is this possible to lock method for one thread and force another to go futher rather than waiting until first thread finish? Can this problem be resolved with static thread or some proper pattern with one instance of mendtioned below service.

For presentation purposes, it can be done with static boolen like below.

public class SomeService
{
  private readonly IRepository _repo;
  public SomeService(IRepository repo)
  {
    _repo = repo;
  }

  private Thread threadOne;

  public static bool isLocked { get; set; }

  public void StartSomeMethod()
  {
    if(!isLocked)
    {
      threadOne = new Thread(SomeMethod);
      isLocked = true;
    }
  }

  public void SomeMethod()
  {
    while(true)
    {
      lots of time
    }
    ...
    isLocked = false;
  }
}

I want to avoid situation when user clicked, by accident, two times to start and accidentailly second thread starts immediatelly after first finished.

Since lock is a language-specific wrapper around Monitor class, you need Monitor.TryEnter:

public class SomeService
{
    private readonly object lockObject = new object();

    public void StartSomeMethod()
    {
        if (Monitor.TryEnter(lockObject))
        {
            // start new thread
        }
    }

    public void SomeMethod()
    {
        try
        {
            // ...
        }
        finally
        {
            Monitor.Exit(lockObject);
        }
    }    
}

Avoid starting new thread with lock, c# try lock c# lock list c# lock await how to stop a thread in java example I want to avoid situation when user clicked, by accident, two times to start and  To prevent those points from unraveling and stretching out of shape, you need to secure them with a back stitch or lock stitch. Backstitching is done by sewing backward and forward at the beginning and end of a seam, on top of the seam stitches, to prevent the stitching from coming undone.

You can use lock :)

object locker = new object();
void MethodToLockForAThread()
{
    lock(locker)
    {
      //put method body here
    }
}

Now the result will be that when this method is called by a thread (any thread) it puts something like flag at the beginning of lock: "STOP! You are not allowed to go any further, you must wait!" Like red light on crossroads. When thread that called this method first, levaes the scope, then at the beginning of the scope this "red light" changes into green.

If you want to not call the method when it is already called by another thread, the only way to do this is by using bool value. For example:

object locker = new object();
bool canAccess = true;
void MethodToLockForAThread()
{
    if(!canAccess)
      return;

    lock(locker)
    {
      if(!canAccess)
        return;

      canAccess = false;            

      //put method body here

      canAccess = true;
    }
}

Other check of canAccess in lock scope is because of what has been told on comments. No it's really thread safe. This is kind of protection that is advisible in thread safe singleton.

EDIT

After some discussion with mjwills I have to change my mind and turn more into Monitor.TryEnter. You can use it like that:

object locker = new object();
void ThreadMethod()
{
  if(Monitor.TryEnter(locker, TimeSpan.FromMiliseconds(1))
  {
     try
     {
       //do the thread code
     }
     finally
     {
       Monitor.Exit(locker);
     }
  } else
    return; //means that the lock has not been aquired
}

Now, lock could not be aquired because of some exception or because some other thread has already acuired it. In second parameter you can pass the time that a thread will wait to acquire a lock. I gave here short time because you don't want the other thread to do the job, when first is doing it. So this solution seems the best.

When the other thread could not acquire the lock, it will go further instead of waiting (well it will wait for 1 milisecond).

Best Practices When Using the Lock Statement, Without delving into the more complex forms of thread coordination mentioned in the One mistake you might make at the beginning is to try to lock on a variable that refers to Avoid Locking on Anything Publicly Accessible. Exclusive locking in threading ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released. To achieve this functionality we have to main exclusive locking constructs are,

You can use a AutoResetEvent instead of your isLocked flag.

AutoResetEvent autoResetEvent = new AutoResetEvent(true);
public void StartSomeMethod()
{
    if(autoResetEvent.WaitOne(0))
    {
        //start thread
    }
}

public void SomeMethod()
{
    try
    {
        //Do your work
    }
    finally
    {
        autoResetEvent.Set();
    }
}

Managed Threading Best Practices, A deadlock occurs when each of two threads tries to lock a resource the other has This particular race condition is easily avoided by using methods of the in C#, Shared Sub New in Visual Basic) has finished running. In second parameter you can pass the time that a thread will wait to acquire a lock. I gave here short time because you don't want the other thread to do the job, when first is doing it. So this solution seems the best. When the other thread could not acquire the lock, it will go further instead of waiting (well it will wait for 1 milisecond).

Java in a Nutshell, At this point, node is the final node in the list, and we have // a lock on it. When you are using locking to prevent threads from accessing the same data at can proceed, neither one can release the lock it holds, and they both stop running. The Thread class defines a number of methods useful for thread management. These include static methods, which provide information about, or affect the status of, the thread invoking the method. The other methods are invoked from other threads involved in managing the thread and Thread object. We'll examine some of these methods in the

Understanding Threads and Locks, When you run a Java application, a new JVM process is started. This section contains basic information about threads and locks in the JRockit JVM. share and update the same data, their activities must be synchronized to avoid errors. Make sure your presser foot is up while threading—many machines lock the tension disks when the presser foot is down, making it impossible to thread the machine through the disks correctly. Remove and re-thread your bobbin. Some machines are particular about which way the bobbin unwinds. Consult your manual to be sure it's inserted correctly.

Programming with POSIX Threads, is already locked, you must unlock all of the mutexes in the set and start over. demonstrates how to avoid mutex deadlocks by applying a backoff algorithm. Only one thread at a time can have the Lock. Any other thread that wants the Lock must wait until the owner of the Lock gives it up. The basic functions to do this are .acquire() and .release(). A thread will call my_lock.acquire() to get the lock. If the lock is already held, the calling thread will wait until it is released.

Comments
  • Possible duplicate of Is there a "try to lock, skip if timed out" operation in C#?
  • "user clicked, by accident, two times" - you can simply prevent this possibility, e.g. by disabling the button. Another possibility is to rethink your design. One thing is creating working thread in the constructor or by using some form of init/deinit pattern to ensure its single-ability, and totally another (bad) idea to create it in some method, which can be called from anywhere. Why don't you create a new instance of SomeService instead of trying to reuse one for multiple cases?
  • I do not want to put working thread inside constructor because with injecting service into controller it instantly create thread which is more load for application, I suppose. By that line of thinking I could create static thread with parameterless constructor and then somehow check state of this thread. Please correct me because I can write rubbish.
  • Should not this object locker be static, because of another threads?
  • Generally speaking, yes it should be static.
  • Your answer is most correct, but do you know how to do it if SomeMethod is async?
  • @gorrch: I usually use this library for async coordination: github.com/StephenCleary/AsyncEx . In your particular case I'd use AsyncManualResetEvent (see "Advanced Usage" section), in despite of there are AsyncLock and AsyncMonitor.
  • Ok, but I do not want that another thread waits. I mean, if it is locked it should omit this method.
  • Ok, take a look at modified version of my post. If you want to no to start a thread at all when another is running, you can do similar, but check canAccess before creating the thread. Remember that canAccess should be set only in lock