Gibt es in C# den Vorgang „Sperren versuchen, bei Zeitüberschreitung überspringen“?

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

  •  08-06-2019
  •  | 
  •  

Frage

Ich muss versuchen, ein Objekt zu sperren, und wenn es bereits gesperrt ist, fahre einfach fort (nach einer Zeitüberschreitung oder ohne Zeitüberschreitung).

Die C#-Sperranweisung blockiert.

War es hilfreich?

Lösung

Ich glaube, dass Sie verwenden können Monitor.TryEnter().

Die Lock-Anweisung wird einfach in a übersetzt Monitor.Enter() Anruf und a try catch Block.

Andere Tipps

Ed hat die richtige Funktion für Sie.Vergessen Sie nicht, anzurufen Monitor.Exit().Sie sollten a verwenden try-finally blockieren, um eine ordnungsgemäße Reinigung zu gewährleisten.

if (Monitor.TryEnter(someObject))
{
    try
    {
        // use object
    }
    finally
    {
        Monitor.Exit(someObject);
    }
}

Ich hatte das gleiche Problem, am Ende habe ich eine Klasse erstellt TryLock das implementiert IDisposable und verwendet dann das using Anweisung zur Steuerung des Sperrbereichs:

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;
        }
    }
}

Und verwenden Sie dann die folgende Syntax zum Sperren:

var obj = new object();

using (var tryLock = new TryLock(obj))
{
    if (tryLock.HasLock)
    {
        Console.WriteLine("Lock acquired..");
    }
}

Sie werden das jetzt wahrscheinlich selbst herausfinden, nachdem die anderen Sie in die richtige Richtung gewiesen haben, aber TryEnter kann auch einen Timeout-Parameter annehmen.

Jeff Richters „CLR Via C#“ ist ein ausgezeichnetes Buch über Details der CLR-Innereien, wenn Sie sich mit komplizierteren Dingen befassen.

Erwägen Sie die Verwendung von AutoResetEvent und seiner Methode WaitOne mit einer Timeout-Eingabe.

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.");
}

Sehen 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 Und https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top