Существует ли в C # конструкция, аналогичная блокировке, которая пропускает блок кода, а не блокирует его? - PullRequest
3 голосов
/ 28 февраля 2011

В фрагменте кода, над которым я работаю, библиотека другого разработчика запускает один из методов моего объекта через регулярные, запланированные интервалы. Я столкнулся с проблемами, когда предыдущий вызов метода моего объекта не завершился в тот момент, когда был достигнут другой интервал, и в мой метод был выполнен второй вызов для повторного выполнения - тогда два потока в итоге наступают друг на друга. Я хотел бы иметь возможность обернуть реализацию метода проверкой, находится ли он в середине обработки, и пропустить блок, если это так.

Блокировка похожа на то, что я хочу, но не совсем покрывает ее, потому что блокировка блокируется, и вызов в мой метод будет принят, как только предыдущий экземпляр снимет блокировку. Это не то, чего я хочу, потому что я мог бы в конечном итоге получить большое количество этих вызовов, резервное копирование и ожидание обработки одного за другим. Вместо этого я бы хотел что-то похожее на блокировку, но без блока, чтобы выполнение продолжалось после блока кода, который обычно был бы окружен блокировкой.

Я придумал счетчик, который будет использоваться с Interlocked.Increment и Interlocked.Decrement, чтобы позволить мне использовать простой оператор if, чтобы определить, следует ли продолжить выполнение метода.

public class Processor
{
    private long _numberOfThreadsRunning = 0;

    public void PerformProcessing()
    {
        long currentThreadNumber Interlocked.Increment(ref _numberOfThreadsRunning);
        if(currentThreadNumber == 1)
        {
            // Do something...
        }
        Interlocked.Decrement(ref _numberOfThreadsRunning);
    }
}

Мне кажется, что я слишком обдумываю это, и, возможно, есть более простое решение.

Ответы [ 3 ]

7 голосов
/ 28 февраля 2011

Вы можете позвонить Monitor.TryEnter и просто продолжить, если он вернет false.

3 голосов
/ 28 февраля 2011
public class Processor
{
    private readonly object lockObject = new object();

    public void PerformProcessing()
    {
        if (Monitor.TryEnter(lockObject) == true)
        {
            try
            {
                // Do something...
            }
            finally
            {
                Monitor.Exit(lockObject);
            }
        }
    }
}
0 голосов
/ 28 февраля 2011

Как насчет добавления флага к объекту.В методе установите флаг true, чтобы указать, что метод выполняется.В самом конце метода сбросьте его на false.Затем вы можете проверить состояние флага, чтобы узнать, можно ли вызвать метод.

...