Me preguntaba lo mismo al tratar de auditar el código de bloqueo correcto. Se me ocurrió un método usando un segundo hilo. Si el bloqueo está disponible para el hilo que llama, pero no está disponible para un segundo hilo, debe ser retenido por el primero.
/// <summary>
/// Utiltity for checking if a lock has already been acquired.
/// WARNING: This test isn't actually thread-safe,
/// it's only really useful for unit tests
/// </summary>
private static bool ObjectIsAlreadyLockedByThisThread(object lockObject)
{
if (!Monitor.TryEnter(lockObject))
{
// another thread has the lock
return false;
}
Monitor.Exit(lockObject);
bool? LockAvailable = null;
var T = new Thread(() =>
{
if (Monitor.TryEnter(lockObject))
{
LockAvailable = true;
Monitor.Exit(lockObject);
}
else
{
LockAvailable = false;
}
});
T.Start();
T.Join();
return !LockAvailable.Value;
}
// Tests:
public static void TestLockedByThisThread()
{
object MyLock = new object();
lock (MyLock)
{
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "True"
}
}
public static void TestLockedByOtherThread()
{
object MyLock = new object();
var T = new Thread(() =>
{
lock (MyLock)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
}
});
T.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
T.Join();
Debug.WriteLine(WasLocked); // prints "False"
}
public static void TestNotLocked()
{
object MyLock = new object();
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "False"
}
No utilizaría esto en el código de producción: hay una condición de carrera que podría explotar. Sin embargo, mis pruebas unitarias son en su mayoría de un solo hilo, así que esto fue útil.
+1, exactamente. Responder esta pregunta sobre el estado pasado del bloqueo solo puede llevarlo a tomar decisiones incorrectas. – JaredPar
Bloqueo cosas para que pueda ver si se están utilizando. p.ej. Por lo tanto, dos subprocesos no destruyen los mismos recursos compartidos. Quiero ver si ese trabajo se está haciendo. Podría hacer lo mismo con un valor IsBeingUsed pero el objeto para el bloqueo ya existe y los bloqueos actúan de la misma manera, con la excepción de poder verificar si están bloqueados sin establecer el valor en bloqueado. – QueueHammer
Al examinar IsBeingUsed, es posible que el subproceso ya haya detenido un trabajo útil, pero es posible que se haya producido un cambio de contexto antes de actualizar IsBeingUsed. –