Как ограничить одним вызовом метода за один раз?

$myarray->[1] означает «поиск индекса 1 в массиве, используя ссылку на массив, сохраненную в $myarray».

$myarray[1] означает «поиск индекса 1 в массиве @myarray».

Две переменные $myarray и @myarray не имеют никакой связи вообще.

5
задан dav_i 29 November 2012 в 16:52
поделиться

7 ответов

Можно использовать именованное Взаимное исключение или именованный Семафор, чтобы гарантировать, что только один держатель Взаимного исключения/Семафора выполняется сразу. Как комментатор указал, имейте в виду, что необходимо бояться отказываться от взаимного исключения или неправильно получать/выпускать семафор.

12
ответ дан 18 December 2019 в 07:32
поделиться

Один путь состоял бы в том, чтобы использовать блокировку:

private readonly object myLock = new object();

private void MyMethod()
{
   lock(myLock)
   {
      //code goes here
   }
}

Это гарантирует, что этот метод никогда не может работать больше что однажды за один раз.

5
ответ дан 18 December 2019 в 07:32
поделиться

Я второй Взаимоисключающее предложение, но Вы могли бы также хотеть смотреть на транзакции. Перенесите свой весь код в транзакцию (это требует a using System.Transactions):

using(TransactionScope scope = new TransactionScope())
{
    try 
    {
        /* ... your current code here */
        scope.Complete();
    }
    catch (Exception e)
    {
        /* Any appropriate error handling/logging here */
    }
    finally
    {
    }
}

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

2
ответ дан 18 December 2019 в 07:32
поделиться

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

1
ответ дан 18 December 2019 в 07:32
поделиться

Некоторые альтернативы:

  1. Можно поместить регистрацию вызова для проверки некоторого флага или Монитора вызова. TryEnter и возврат с ошибкой / ничто, если отрицательный.
  2. Можно стоять в очереди вызовы (если Вам нужен этот метод для выполнения несколько раз), и только вызовите, когда Монитор был сообщен.
  3. Если Вы не возражаете блокироваться, и метод находится на отдельном потоке, можно присоединиться к потоку метода, Вы хотите ожидать.

Я уверен, что существуют другие.

1
ответ дан 18 December 2019 в 07:32
поделиться

Это походит на последовательный рабочий процесс... Вы рассмотрели использование платформы рабочего процесса?

0
ответ дан 18 December 2019 в 07:32
поделиться

Если Вы не возражаете ограничивать один поток за один раз всем объектом, то можно использовать:

Контексты синхронизации

  1. Имейте свой класс, наследовались ContextBoundObject
  2. Примените [Синхронизация] атрибут к классу.

CLR только позволит одному потоку за один раз выполнять код на экземпляр этого класса. Другие заблокируются, пока блокировка не выпущена текущим потоком.

0
ответ дан 18 December 2019 в 07:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: