Para minimizar los efectos secundarios, el objeto que está siendo bloqueado en no debe ser el objeto que está siendo manipulado, sino más bien un objeto independiente designado para el bloqueo.
Dependiendo de sus necesidades, hay algunas opciones para manejar este problema:
Variante A: el bloqueo de objetos privada
Elija esta opción si lo que desea es asegurarse de que DoSomething
no entra en conflicto con una instancia paralela de DoSomething
.
private static readonly object doSomethingLock = new object();
public static void DoSomething (string param1, string param2, SomeObject o)
{
//.....
lock(doSomethingLock)
{
o.Things.Add(param1);
o.Update();
// etc....
}
}
Variante B: Pase el bloqueo de objetos como parámetro
Elija esta opción si el acceso a o
debe ser flujos seguros incluso fuera de DoSomething
, es decir, si existe la posibilidad de que alguien escribe un método DoSomethingElse
que discurre en paralelo a DoSomething
y que no debe interferir con el bloque lock
en DoSomething
:
public static void DoSomething (string param1, string param2, SomeObject o, object someObjectLock)
{
//.....
lock(someObjectLock)
{
o.Things.Add(param1);
o.Update();
// etc....
}
}
Variante C: Crear SyncRoot propiedad
Si usted tiene control sobre la ejecución de SomeObject
, podría ser conveniente proporcionar el bloqueo de objetos como una propiedad. De esta manera, se puede aplicar la variante B sin tener que pasar alrededor de un segundo parámetro:
class SomeObject
{
private readonly object syncRoot = new object();
public object SyncRoot { get { return syncRoot; } }
...
}
A continuación, sólo tiene que utilizar lock(o.SyncRoot)
en DoSomething
. Ese es el patrón que algunas de las clases de BCL usan, por ejemplo, Array.SyncLock, ICollection.SyncRoot.
Creo que 'doSomethingLock' se suele llamar' syncRoot'. – Sung
Creo que veo por qué ahora. No puedo bloquear la referencia pasada al método porque cualquier persona que use ese objeto también podrá bloquearlo. En efecto, es lo mismo que bloquear (esto) pero a una clase diferente. – ghostJago
Los objetos de bloqueo también deben ser de solo lectura. –