Примитив синхронизации "заблокировать один раз" - PullRequest
1 голос
/ 09 марта 2011

Мне нужен примитив синхронизации, который похож на Monitor, но не требует выхода из него столько раз, сколько я его ввел.Если я войду в Монитор одним потоком, а затем повторно введу его тем же потоком, мне нужно будет дважды вызвать Monitor.Exit.Но мне нужно выйти из него одним вызовом.

Теперь я использую какую-то оболочку Monitor, которая не входит в Monitor, если она уже была введена текущим потоком (и поэтому тогда я могу выйти из нее однимвызов).Но может быть .NET Framework содержит один?

Ответы [ 2 ]

1 голос
/ 09 марта 2011

Мне любопытно узнать, почему вы бы звонили Monitor.Enter несколько раз без равного количества звонков на Monitor.Exit.Обычно любой такой код синхронизации будет выглядеть следующим образом:

try
{
    Monitor.Enter(lockObject);
    // some code that needs to be synchronized
}
finally
{
    Monitor.Exit(lockObject);
}

Предполагается, что вы используете try / finally везде, где вы получаете блокировку с использованием Monitor.Enter (что для вас должно быть), Я не могу понять, зачем вам нужен этот "блокирующий один раз" класс, о котором вы спрашиваете.

На самом деле, вам все равно в принципе никогда не придется делать это самостоятельно, так как гораздо более простой подходв сущности, это то же самое, что использовать выражение lock:

lock (lockObject)
{
    // some code that needs to be synchronized
}

Тем не менее, я могу просто что-то упустить.

0 голосов
/ 09 марта 2011

откуда вы знаете, что это тот же поток, и как вы гарантируете, что когда этот поток уйдет, он вызовет выход до того, как он уйдет?

Судя по всему, вам просто нужно что-то еще (ввнешний уровень), который имеет замок.Может быть, метод «точки входа», который блокирует и вызывает другой метод, имеющий основную часть работы, тогда вы можете вызывать этот другой метод много раз, не проходя мимо блокировки.

public static void MethodOne()
{
  lock (lockObj)
  {
    MethodTwo();
  }
}

private static void MethodTwo()
{
  //This method can be called multiple times
  //without going past MethodOne and so you only
  //lock once
}

private static void MethodThree()
{
}
...