Există o operație "încearcă să blochezi, săriți dacă a expirat" în C #?

Trebuie să încerc să blochez un obiect și, dacă este deja blocat, trebuie doar să continue (după o perioadă de timp sau fără el).

Instrucțiunea de blocare C# blochează.

0
fr hi bn

5 răspunsuri

Ed are funcția potrivită pentru tine. Nu uitați să sunați la Monitor.Exit() . Ar trebui să utilizați un bloc try-finally pentru a garanta curățarea corespunzătoare.

if (Monitor.TryEnter(someObject))
{
    try
    {
       //use object
    }
    finally
    {
        Monitor.Exit(someObject);
    }
}
0
adăugat
@ceztko, poți clarifica? În general, eliberarea resurselor N în, de exemplu, C# necesită blocuri N-imbricate în încercare. Instrucțiunea de utilizare ajută la evitarea acestei situații numai pentru IDispozabile. Sari peste blocurile try-finally poate duce la scurgeri de resurse în cazul unei excepții. De exemplu, documentația Monitor clarifică că blocul final este necesar. Ciudat, legătura lui Ed neglijează acest lucru.
adăugat autor Derek Park, sursa
+1, mulțumesc! Propune o mică schimbare, dacă doriți, doar pentru a vă reaminti că (aproape) este întotdeauna posibil să utilizați construcții/modele avansate fără a acoperi cusăturile pe termen nelimitat.
adăugat autor ceztko, sursa

Veți găsi probabil acest lucru pentru dvs. acum că ceilalți v-au indicat în direcția corectă, dar TryEnter poate lua, de asemenea, un parametru timeout.

Jeff Richter, "CLR Via C #", este o carte excelentă despre detaliile învelișurilor CLR dacă intri în lucruri mai complicate.

0
adăugat

Cred că puteți folosi < code> Monitor.TryEnter() .

Instrucțiunea de blocare se traduce doar într-un apel Monitor.Enter() și într-un bloc try catch .

0
adăugat
Dacă am de-a face cu concurrency între procese? Există vreo modalitate de a folosi un Mutex într-un mod similar?
adăugat autor Mihai Todor, sursa

Am avut aceeasi problema, am incheiat crearea unei clase TryLock care implementeaza IDisposable si apoi foloseste instructiunea folosind pentru a controla scopul blocarii:

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

Apoi utilizați următoarea sintaxă pentru a bloca:

var obj = new object();

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

Luați în considerare utilizarea AutoResetEvent și a metodei sale WaitOne cu o intrare de tip timeout.

Vedeți https://msdn. microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx și https://msdn.microsoft.com/en-us/library/cc190477 (v = vs.110) .aspx

0
adăugat