I have a method in a multi-threaded application and I\'d like the following behavior when this method is invoked:
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);
}
}
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
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);
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.