Exit a method if another thread is executing it

后端 未结 4 2130
既然无缘
既然无缘 2021-02-07 13:18

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 m
相关标签:
4条回答
  • 2021-02-07 13:55

    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);
        }
    
    }
    
    0 讨论(0)
  • 2021-02-07 14:09

    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

    0 讨论(0)
  • 2021-02-07 14:10

    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);
    
    0 讨论(0)
  • 2021-02-07 14:14

    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.

    0 讨论(0)
提交回复
热议问题