2011-11-17 3 views
3

Я столкнулся с ситуацией, которая заставляет меня заблокировать объект блокировки, который находится внутри объекта экземпляра, который я хочу знать, это правда или нет?Объект блокировки C# внутри объекта объекта

для уточнения:

public class classA 
{ 
    object objLock = new object(); 
    public void MethodA(object objClassA) 
    { 
     classA cls = (classA)objClassA; 
     lock(cls.objLock) 
     { 
      Do something with cls 
     } 
    } 
} 

это позволено сделать это?

+1

То, что вы делаете, является синтаксически законным, но код выглядит подозрительным. – Kit

ответ

2

Это прекрасно. Это законный C#. На самом деле это предпочтительный способ вместо блокировки . Поскольку этот может быть заблокирован из-за пределов класса, тогда как objLock будучи частным может быть заблокирован только в классе, давая вам лучше контролировать и избежать некоторых условий тупиковых

Однако отливка потенциально может бросить исключение. Возможно, вам захочется обработать этот сценарий

+0

Разве это не так, потому что он блокирует объект в другом экземпляре, что он все еще может столкнуться с проблемами взаимоблокировки (например, блокировка частной переменной в другом экземпляре действительно не отличается от блокировки на «этом»)? Как уже упоминалось в другом ответе, никакой внешний код не должен блокировать объекты внутри класса (или самого класса), даже если эти внешние объекты являются экземплярами одного и того же класса. –

+0

моя большая забота о тупике. Но я обнаружил, что использование синхронизации потоков может решить эту проблему. «Что-то с cls» в моем вопросе находится внутри цикла while. – amir110

5

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

public class classA 
{ 
    private readonly object objLock = new object(); 

    public void MethodA(object objClassA) 
    { 
     classA cls = (classA)objClassA; 

     cls.DoSomething(); 
    } 

    private void DoSomething() 
    { 
     lock (this.objLock) 
     { 
      Do something with cls 
     } 
    } 
}