¿Existe una operación de "intentar bloquear, omitir si se agota el tiempo de espera" en C#?
-
08-06-2019 - |
Pregunta
Necesito intentar bloquear un objeto y, si ya está bloqueado, continuar (después del tiempo de espera o sin él).
La declaración de bloqueo de C# está bloqueando.
Solución
Creo que puedes usar Monitor.TryEnter()
.
La declaración de bloqueo simplemente se traduce en una Monitor.Enter()
llamada y un try catch
bloquear.
Otros consejos
Ed tiene la función adecuada para ti.No olvides llamar Monitor.Exit()
.Deberías usar un try-finally
bloque para garantizar una limpieza adecuada.
if (Monitor.TryEnter(someObject))
{
try
{
// use object
}
finally
{
Monitor.Exit(someObject);
}
}
Tuve el mismo problema, terminé creando una clase. TryLock
que implementa IDisposable y luego usa el using
Declaración para controlar el alcance del bloqueo:
public class TryLock : IDisposable
{
private object locked;
public bool HasLock { get; private set; }
public TryLock(object obj)
{
if (Monitor.TryEnter(obj))
{
HasLock = true;
locked = obj;
}
}
public void Dispose()
{
if (HasLock)
{
Monitor.Exit(locked);
locked = null;
HasLock = false;
}
}
}
Y luego use la siguiente sintaxis para bloquear:
var obj = new object();
using (var tryLock = new TryLock(obj))
{
if (tryLock.HasLock)
{
Console.WriteLine("Lock acquired..");
}
}
Probablemente lo descubrirá usted mismo ahora que los demás le han indicado la dirección correcta, pero TryEnter también puede tomar un parámetro de tiempo de espera.
"CLR Via C#" de Jeff Richter es un libro excelente sobre los detalles de las entrañas de CLR si te adentras en temas más complicados.
Considere usar AutoResetEvent y su método WaitOne con una entrada de tiempo de espera.
static AutoResetEvent autoEvent = new AutoResetEvent(true);
if(autoEvent.WaitOne(0))
{
//start critical section
Console.WriteLine("no other thread here, do your job");
Thread.Sleep(5000);
//end critical section
autoEvent.Set();
}
else
{
Console.WriteLine("A thread working already at this time.");
}
Ver https://msdn.microsoft.com/en-us/library/cc189907(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx y https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx