How to make a method exclusive in a multi-threaded context?

I have a method that should be executed in an exclusive way. This is basically a multi-threaded application in which the method is called periodically by a timer, but which can also be started manually using a user action.

Take an example:

  • The timer expires, so the method is called. The task may take several seconds.

  • Immediately after this, the user clicks on, which should cause the same task: BAM. It does nothing since this method is already running.

I used the following solution:

public void DoRecurentJob()
{
    if(!Monitor.TryEnter(this.lockObject))
    {
        return;
    }

    try
    {
        // Do work
    }
    finally 
    {
        Monitor.Exit(this.lockObject);
    }
}

Where lockObjectdeclared as follows:

private readonly object lockObject = new object();

Change . There will be only one instance of an object that supports this method, so I updated the lock object so that it is non-static.

? , , - ?

+3
8

, , . , , , , Monitor.Exit().

static static .

+4

Mutex Semaphore, , ( ), , , .

, , , , .

+2

: lockObject , "this.lockObject" . ( , , ), , , . , , ?

? , . , , , - , , - , , .

, , . , , , . ( "if" "try", , - , CLR.)

+2

, , . , , , .

, , .

public class MyClass
{ 
    public void AccessResource()
    {
        OneAtATime(this);
    }

    private static void OneAtATime(MyClass instance) 
    { 
       if( !Monitor.TryEnter(lockObject) )
       // ...
+1

, Microsoft lock Monitor . .

public class MyClass
{

  // Used as a lock context
  private readonly object myLock = new object();

  public void DoSomeWork()
  {
    lock (myLock)
    {
      // Critical code section
    }
  }
}

MyClass, :

private static readonly object myLock = new object();
+1

, . , . , , , . .

, , , . , , .

0

- MethodImplOptions.Synchronized , :

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

, . , . Java synchronized - , .

0

, , , , . :

https://codereview.stackexchange.com/questions/16150/singleton-task-running-using-tasks-await-peer-review-challenge

private queued = false;
private running = false;
private object thislock = new object();

void Enqueue() {
    queued = true;
    while (Dequeue()) {
        try {
            // do work
        } finally {
            running = false;
        }
    }
}

bool Dequeue() {
    lock (thislock) {
        if (running || !queued) {
            return false;
        }
        else
        {
            queued = false;
            running = true;
            return true;
        }
    }
}
0

Source: https://habr.com/ru/post/1697659/


All Articles