2015-07-15 6 views
2

У меня есть метод, к которому обращаются из нескольких потоков одновременно, и я хочу убедиться, что только один поток может находиться внутри тела любого метода.Заблокировать использование всех методов

Может ли этот код быть реорганизован на что-то более общее? (Кроме блокировки внутри государственного собственности

public class StateManager : IStateManager 
{ 
    private readonly object _lock = new object(); 
    public Guid? GetInfo1() 
    { 
     lock (_lock) 
     { 
      return State.Info1; 
     } 
    } 

    public void SetInfo1(Guid guid) 
    { 
     lock (_lock) 
     { 
      State.Info1 = guid; 
     } 
    } 

    public Guid? GetInfo2() 
    { 
     lock (_lock) 
     { 
      return State.Info2; 
     } 
    } 

    public void SetInfo2(Guid guid) 
    { 
     lock (_lock) 
     { 
      State.Info2 = guid; 
     } 
    } 
} 
+0

Я не знаю ни одного способа, чтобы зафиксировать, как это без заявления отдельных замков, как у вас есть. Мне интересно узнать, не ошибаюсь ли я! :) – Chris

+0

Я не думаю, что любой из ваших методов небезопасен, почему вы даже блокируете здесь? – Andrey

+0

Андрей - это фиктивный пример. Я делаю больше в телах методов. –

ответ

2

Может быть что-то вроде:

private void LockAndExecute(Action action) 
{ 
    lock (_lock) 
    { 
     action(); 
    } 
} 

Тогда ваши методы могут выглядеть следующим образом:

public void DoSomething() 
{ 
    LockAndExecute(() => Console.WriteLine("DoSomething")); 
} 

public int GetSomething() 
{ 
    int i = 0; 
    LockAndExecute(() => i = 1); 
    return i; 
} 

Я не уверен, что это на самом деле вам очень экономно, но возвратные значения немного больны.

Хотя вы могли бы работать вокруг этого, добавив еще один способ, как это:

private T LockAndExecute<T>(Func<T> function) 
{ 
    lock (_lock) 
    { 
     return function(); 
    } 
} 

Так что теперь мой GetSomething метод намного чище:

public int GetSomething() 
{ 
    return LockAndExecute(() => 1); 
} 

Опять же, не уверен, что вы набирают много с точки зрения менее набрав, но, по крайней мере, вы знаете, что каждый вызов блокируется на тем же объектом.

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

public void DoSomething() 
{ 
    // check some preconditions 
    // maybe do some logging 
    try 
    { 
     // do actual work here 
    } 
    catch (SomeException e) 
    { 
     // do some error handling 
    } 
} 

В этом случае, извлечение всех предварительных условий и обработка ошибок в одном месте могут быть весьма полезными:

private void CheckExecuteAndHandleErrors(Action action) 
{ 
    // preconditions 
    // logging 
    try 
    { 
     action(); 
    } 
    catch (SomeException e) 
    { 
     // handle errors 
    } 
} 
0

Использование действия или функции Делегат.

Создание метода как

public T ExecuteMethodThreadSafe<T>(Func<T> MethodToExecute) 
    { 
     lock (_lock) 
     { 
      MethodToExecute.Invoke(); 
     } 
    } 

и использовать его как

public T GetInfo2(Guid guid) 
     { 
      return ExecuteMethodThreadSafe(() => State.Info2); 
     } 
Смежные вопросы