Y a t-il essayer de verrouiller, ignorer si l'expiration de l'opération” en C#?
-
08-06-2019 - |
Question
J'ai besoin d'essayer de se verrouiller sur un objet, et si sa déjà verrouillé juste continuer (après le temps, ou sans elle).
L'instruction C# lock bloque.
La solution
Je crois que vous pouvez utiliser Monitor.TryEnter()
.
L'instruction lock juste se traduit par une Monitor.Enter()
appel et une try catch
le bloc.
Autres conseils
Ed a le droit de la fonction pour vous.Il suffit de ne pas oublier d'appeler Monitor.Exit()
.Vous devez utiliser un try-finally
bloc afin de garantir un bon nettoyage.
if (Monitor.TryEnter(someObject))
{
try
{
// use object
}
finally
{
Monitor.Exit(someObject);
}
}
J'ai eu le même problème, j'ai fini par la création d'une classe TryLock
qui met en œuvre IDisposable et utilise ensuite l' using
déclaration de contrôler la portée de la serrure:
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;
}
}
}
Et puis, utilisez la syntaxe suivante pour verrouiller:
var obj = new object();
using (var tryLock = new TryLock(obj))
{
if (tryLock.HasLock)
{
Console.WriteLine("Lock acquired..");
}
}
Vous trouverez probablement ceci pour vous-même maintenant que les autres ont pointé dans la bonne direction, mais TryEnter pouvez également prendre un paramètre de délai d'attente.
Jeff de Richter "CLR Via C#" est un excellent livre sur des détails des CLR entrailles si vous obtenez en plus des choses compliquées.
Pensez à utiliser AutoResetEvent et sa méthode WaitOne avec un délai d'attente d'entrée.
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.");
}
Voir 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 et https://msdn.microsoft.com/en-us/library/cc190477(v=vs. 110).aspx