Закройте метод, если его выполняет другой поток
У меня есть метод в многопоточном приложении, и я хотел бы следующее поведение при вызове этого метода:
- если никакие другие потоки в настоящее время не выполняют метод, выполните его.
- если другой поток в настоящее время выполняет метод, то выйдите из метода без его выполнения.
на lock
оператор в C# полезен для ожидания завершения выполнения потока, но я не хочу сериализовать доступ к этому методу но скорее обходите выполнение этого метода, если он выполняется другим потоком.
4 ответов
вы можете сделать это с помощью монитора.TryEnter, но, возможно, проще: 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);
}
}
создайте переменную bool где-нибудь еще, установите true при запуске метода и false при выходе из метода, перед запуском метода проверьте, является ли переменная false, а затем запустите другой выход из метода
вот вспомогательный метод для этой цели:
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);
}
}
}
и использовать его как:
private int _isTuning = 0;
private void Tune() { ... }
...
Throttle.RunExclusive(ref _isTuning, Tune);