2015-08-17 3 views
3

Хорошо ли работает следующий код для блокировки простых объектов?Объект CQ Locking Vault

Если да, то почему он больше не используется/как его можно улучшить? Если нет, то почему?

public class Vault<T> 
{ 
    private object key = new object(); 
    private T _Item; 

    public Vault() { } 

    public Vault(T Deposit) 
    { 
     Set(Deposit); 
    } 

    public T Get() 
    { 
     lock (key) 
     { 
      return _Item; 
     } 
    } 
    public void Set(T Deposit) 
    { 
     lock (key) 
     { 
      _Item = Deposit; 
     } 
    } 
} 
+0

реальность в том, что блокировка для одного свойства редко требуется (особенно для ссылочных типов, существует некоторое значение для типов значений в коде). Когда вам нужно блокировать несколько обновлений полей, это почти всегда одноразовый случай, и общий помощник не поможет :). –

+0

@AlexeiLevenkov - одно из преимуществ, которое может быть в ситуациях, когда вам нужен барьер памяти, чтобы убедиться, что у нескольких потоков есть текущее значение –

+0

@ScottChamberlain да, ... к сожалению, недостаток предлагаемого кода теперь у вас есть это значение в экземпляр другого ссылочного типа, и, следовательно, вы должны убедиться, что ссылка не изменилась - вернитесь к блокировке ссылки на 'Vault ' в оригинальном классе :) ... и сделать его 'struct' не улучшающим ситуацию с точки зрения «это правильный код». –

ответ

0

хорошо ли следующий код работает для блокировки простых объектов? Ответ: Да.

заявление замок является C# синтаксически Monitor.Enter и Monitor.Exit На данный момент этого ответа вы можете увидеть этот класс не является устаревшим, может быть, может ответить на ваш вопрос: Так почему же это не более. Для справки вы можете увидеть MSDN Monitor class. Накладные расходы оператора блокировки составляют 20ns

Всего несколько комментариев, если внутри вашего оператора блокировки выбрано исключение, которое может быть вредным, если вы не считаете попытку, связанную с блокировкой, решение для сложный случай - «откат». На приведенном ниже образце вы можете потерять деньги, если выбрано исключение.

public void Set(T Deposit) 
    { 
     lock (key) 
     { 
      _Item -= Deposit/x; x can take the value of zero 
     } 
    } 

Для ваших улучшений рассмотрит примерочный улов , чтобы избежать этой проблемы.

В случае, если вы хотите использовать класс Monitor непосредственно Monitor.Enter имеет дополнительный параметр реф Его lockTaken, который может быть полезным, правильный образец, чтобы использовать это (именно как C# 4.0 переводит стопорное заявление)

bool lockTaken = false; 
try 
{ 
    Monitor.Enter (_locker, ref lockTaken); 
    // Do your stuff... 
} 
finally { if (lockTaken) Monitor.Exit (_locker); } 

Вы можете прочитать больше о замке здесь Albahari