J'ai besoin d'essayer de verrouiller sur un objet, et s'il est déjà verrouillé, continuez juste (après expiration, ou sans).Y a-t-il une opération "essayer de verrouiller, sauter si le délai est dépassé" en C#?
L'instruction C# lock bloque.
J'ai besoin d'essayer de verrouiller sur un objet, et s'il est déjà verrouillé, continuez juste (après expiration, ou sans).Y a-t-il une opération "essayer de verrouiller, sauter si le délai est dépassé" en C#?
L'instruction C# lock bloque.
Je crois que vous pouvez utiliser Monitor.TryEnter()
.
L'instruction lock se traduit simplement par un appel Monitor.Enter()
et un bloc try catch
.
Ed a la bonne fonction pour vous. N'oubliez pas d'appeler le Monitor.Exit()
. Vous devez utiliser un bloc try-finally
pour garantir un nettoyage correct.
if (Monitor.TryEnter(someObject))
{
try
{
// use object
}
finally
{
Monitor.Exit(someObject);
}
}
+1, merci! Proposé un petit changement, si vous voulez, juste pour rappeler qu'il est (presque) toujours possible d'utiliser des constructions/modèles avancés sans imbriquer indéfiniment des accolades. – ceztko
@ceztko, pouvez-vous clarifier? En général, la libération de ressources N dans, par exemple, C# nécessite N blocs try-finally imbriqués. L'instruction using permet d'éviter cela uniquement pour IDisposables. Ignorer les blocs try-finally peut entraîner des fuites de ressources en cas d'exception. Par exemple, la documentation [Monitor] (http://msdn.microsoft.com/en-us/library/aa720302 (v = VS.71) .aspx) précise que le bloc finally est nécessaire. Bizarrement, le lien d'Ed néglige cela. –
Vous trouverez probablement ceci pour vous-même maintenant que les autres vous ont fait dans la bonne direction, mais TryEnter pouvez également prendre un paramètre de délai d'attente.
Le "CLR Via C#" de Jeff Richter est un excellent livre sur les détails des entrailles CLR si vous vous lancez dans des choses plus compliquées.
J'ai eu le même problème, je fini par créer une classe TryLock
qui implémente IDisposable et utilise ensuite la déclaration using
pour 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..");
}
}
Envisagez d'utiliser AutoResetEvent et sa méthode WaitOne avec une entrée de délai.
Voir 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
si je fais face à la concurrence inter-processus? Existe-t-il un moyen d'utiliser un Mutex de la même manière? –