Y a t-il essayer de verrouiller, ignorer si l'expiration de l'opération” en C#?

StackOverflow https://stackoverflow.com/questions/8546

  •  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.

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top