Exit a method if another thread is executing it

做~自己de王妃 提交于 2021-02-17 21:31:54

问题


I have a method in a multi-threaded application and I'd like the following behavior when this method is invoked:

  1. If no other threads are currently executing the method, execute it.
  2. If another thread is currently executing the method then exit the method without executing it.

The lock statement in C# is useful for waiting until a thread has completed execution, but I don't want to serialize access to this method but rather bypass executing said method if it is being executed by another thread.


回答1:


I suppose I don't understand... if it should only be called by one thread at a time, why are multiple threads calling it to begin with?

Anyway, you can use Monitor.TryEnter(). It doesn't block and returns false if it fails to acquire a lock. In that case you can just return from the function.




回答2:


You can do this using Monitor.TryEnter, but perhaps more simply: Interlocked:

int executing; // make this static if you want this one-caller-only to
               // all objects instead of a single object
void Foo() {
    bool won = false;
    try {
        won = Interlocked.CompareExchange(ref executing, 1, 0) == 0;
        if(won) {
           // your code here
        }
    } finally {
        if(won) Interlocked.Exchange(ref executing, 0);
    }

}



回答3:


create bool variable somewhere else, set on true when start method and to false on exit from method, before run method check if variable is false then run else exit from method




回答4:


Here's a helper method for this purpose:

static class Throttle
{
    public static void RunExclusive(ref int isRunning, Action action)
    {
        if (isRunning > 0) return;

        bool locked = false;
        try
        {
            try { }
            finally
            {
                locked = Interlocked.CompareExchange(ref isRunning, 1, 0) == 0;
            }

            if (locked) action();
        }
        finally 
        { 
            if (locked) 
                Interlocked.Exchange(ref isRunning, 0); 
        }
    }
}

and use it like:

private int _isTuning = 0;
private void Tune() { ... }

...

Throttle.RunExclusive(ref _isTuning, Tune);


来源:https://stackoverflow.com/questions/12412204/exit-a-method-if-another-thread-is-executing-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!