2015-02-28 5 views

ответ

1

Нет, но вы можете инкапсулировать блокировку в классе, что делает:

Interlocked.Increment 

перед входом в замок на прилавке и

Interlocked.Decrement 

после достижения блокировки

Например :

public sealed class SimpleCountedLock 
{ 
    private readonly object obj = new object(); 

    private int counter; 

    public int Counter 
    { 
     get 
     { 
      // Guaranteed to return the last value 
      return Interlocked.CompareExchange(ref counter, 0, 0); 
     } 
    } 

    public void Enter(ref bool lockTaken) 
    { 
     int cnt = int.MinValue; 

     try 
     { 
      try 
      { 
      } 
      finally 
      { 
       // Finally code can't be interrupted by asyncronous exceptions 
       cnt = Interlocked.Increment(ref counter); 
      } 

      Monitor.Enter(obj, ref lockTaken); 
     } 
     finally 
     { 
      // There could be an asynchronous exception (Thread.Abort for example) 
      // between the try and the Interlocked.Increment . 
      // Here we check if the Increment was done 
      if (cnt != int.MinValue) 
      { 
       Interlocked.Decrement(ref counter); 
      } 
     } 
    } 

    public void Exit() 
    { 
     Monitor.Exit(obj); 
    } 
} 

Использование:

SimpleCountedLock cl = new SimpleCountedLock(); 

, а затем в различных нитей:

bool lockTaken = false; 

try 
{ 
    cl.Enter(ref lockTaken); 
    // Your code. The lock is taken 
} 
finally 
{ 
    if (lockTaken) 
    { 
     cl.Exit(); 
    } 
} 

Аргументация реф lockTaken здесь: Monitor.Enter.

+0

Операции над целыми числами уже являются атомарными, верно? – toplel32

+0

Оказывается, что нет; http://stackoverflow.com/questions/4628243/is-the-operator-thread-safe – toplel32

+0

@ toplel32 Yep, '++' и '--' не являются потокобезопасными и не читают 64-битные значения (' long '), когда ваше приложение составляет 32 бита – xanatos

Смежные вопросы