multithreading - lock - ¿Hay alguna forma de detectar si un objeto está bloqueado?
synclock vb (5)
Actualmente puede llamar a Monitor.TryEnter para inspeccionar si el objeto está bloqueado o no.
En .NET 4.0, el equipo de CLR agregará la "API de inspección de bloqueo"
Aquí hay una cita del artículo de Rick Byers :
inspección de cerradura
Estamos agregando algunas API simples a ICorDebug que le permiten 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).
Entonces, con esta API podrás comprobar:
1) ¿Qué objeto tiene un bloqueo?
2) ¿Quién lo está esperando?
Espero que esto ayude.
¿Hay alguna forma 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.
Podría programarlo, digamos usando delegar pero sería feo.
Monitor.TryEnter
tendrá éxito si el objeto no está bloqueado, y devolverá falso si en este 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.
Siempre puede llamar al método TryEnter
estático en la clase Monitor
usando un valor de 0 para que el valor espere. Si está bloqueado, la llamada devolverá falso.
Sin embargo, el problema aquí es que debe asegurarse de que la lista a la que está intentando sincronizar el acceso esté bloqueada en sí misma para sincronizar el acceso.
En general, es una mala práctica utilizar el objeto que el acceso se está sincronizando como el objeto para bloquear (exponiendo demasiados detalles internos de un objeto).
Recuerde, la cerradura puede estar en cualquier otra cosa, así que simplemente llamar a esta lista no tiene sentido a menos que esté seguro de que esa lista es lo que se está bloqueando.
No estoy seguro de si una llamada estática a TryEnter con un tiempo de 0 garantizará que el bloqueo no se obtendrá si está disponible. La solución que hice para probar en modo de depuración que la variable de sincronización estaba bloqueada fue 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
Determina si el hilo actual mantiene el bloqueo en el objeto especificado.
Disponible desde 4.5