2009-08-19 31 views
45

¿Hay alguna manera de determinar si un objeto está bloqueado en C#? Tengo la posición poco envidiable, a través del diseño donde estoy leyendo desde una cola dentro de una clase, y necesito volcar los contenidos en una colección en la clase. Pero esa colección también es de lectura/escritura desde una interfaz fuera de la clase. Entonces, obviamente, puede haber un caso cuando se está escribiendo la colección, al mismo tiempo que quiero escribir en ella.¿Hay alguna forma de detectar si un objeto está bloqueado?

que podría programar alrededor de ella, dicen que el uso de delegado pero sería fea.

+0

Sí, Gracias amigos. Más o menos confirma lo que pensaba ya. –

Respuesta

40

Siempre puede llamar al TryEnter method estático en el Monitor class usando un valor de 0 para el valor de espera. Si está bloqueado, la llamada devolverá falso.

Sin embargo, el problema aquí es que usted necesita para asegurarse de que la lista que está intentando sincronizar el acceso a la que se está encerrado en sí mismo con el fin de sincronizar el acceso.

Por lo general es una mala práctica para utilizar el objeto de que el acceso se está sincronizado como el objeto de bloquear el (exponer demasiado de los detalles internos de un objeto).

Recuerde, el bloqueo podría estar en cualquier otra cosa, por lo que acaba de llamar a este en esa lista no tiene sentido a menos que esté seguro de que la lista es lo que está siendo bloqueado en.

10

Monitor.TryEnter tendrá éxito si el objeto no está bloqueado, y volverá falso si en este mismo momento, el objeto está bloqueado. Sin embargo, tenga en cuenta que aquí hay una carrera implícita: la instancia que este método devuelve, el objeto puede no estar bloqueado más.

6

Actualmente puede llamar a Monitor.TryEnter para inspeccionar si el objeto está bloqueado o no.

En .NET CLR 4.0 equipo va a añadir "Lock API de inspección"

Aquí es una cita de Rick Byers artículo:

inspección bloqueo
estamos añadiendo algunas API simples a ICorDebug que le permite explorar bloqueos administrados (Monitores). Por ejemplo, si un hilo está bloqueado esperando un bloqueo, puede encontrar qué otro hilo está sujetando el bloqueo (y si hay un tiempo de espera).

Así pues, con esta API podrá comprobar:
1) ¿Qué objeto es la celebración de una cerradura?
2) ¿Quién lo está esperando?

Espero que esto ayude.

+0

Interesante. Bob. –

7

no estoy seguro de si una llamada estática a TryEnter con un tiempo de 0 garantizará que la cerradura no será adquirida si está disponible. La solución que hice para poner a prueba en modo de depuración que la variable de sincronización estaba cerrada fue utilizando la siguiente:

#if DEBUG 
// Make sure we're inside a lock of the SyncRoot by trying to lock it. 
// If we're able to lock it, that means that it wasn't locked in the first 
// place. Afterwards, we release the lock if we had obtained it. 
bool acquired = false; 
try 
{ 
    acquired = Monitor.TryEnter(SyncRoot); 
} 
finally 
{ 
    if (acquired) 
    { 
     Monitor.Exit(SyncRoot); 
    } 
} 
Debug.Assert(acquired == false, "The SyncRoot is not locked."); 
#endif 
+2

La variable 'isNotLocked' se llama bastante mal. Desbloquea si 'isNotLocked' es verdadero - aunque técnicamente es correcto porque' isNotLocked' será verdadero cuando el candado se adquirió con éxito, el código anterior es realmente malo de leer. Si alguien más tiene que trabajar en esto, tendrá un momento WTF. – ChrisWue

+2

No funciona si el subproceso en el que se ejecuta es el mismo que posee el bloqueo. Dirá que el bloqueo es gratis cuando realmente no lo es. –

Cuestiones relacionadas