Mit Timeout-Muster sperren

lock verwendet dieses Muster

if(Monitor.Enter(lock))
    try
    {
        ...
    }
    finally { Monitor.Exit(lock); } // using this style to reduce post "height"

wenn wir nicht unendlich warten wollen, können wir eine Zeitüberschreitung vorsehen

if(!Monitor.TryEnter(lock, timeout))
    throw new TimeoutException();
try
{
    ...
}
finally { Monitor.Exit(lock); }

Ich habe ein Szenario, in dem die Methode mehrere Sperren erhalten muss, bevor sie etwas unternimmt. Das sieht schrecklich aus:

if(!Monitor.TryEnter(lockA, timeout))
    throw new TimeoutException();
try
{
    if(!Monitor.TryEnter(lockB, timeout))
        throw new TimeoutException();
    try
    {
        if(!Monitor.TryEnter(lockC, timeout))
            throw new TimeoutException();
        try
        {
            ... // more of such constructions
        }
        finally { Monitor.Exit(lockC); }
    }
    finally { Monitor.Exit(lockB); }
}
finally { Monitor.Exit(lockA); }

Es hat Probleme:

sieht hässlich aus (der Methodencode ist eingerückt, stellen Sie sich vor, wie es aussehen wirdlockZ) kann gelöst werden, indem Methodencode in eine andere Methode eingefügt wird.

sperren erfolgt synchron, daher kann der schlimmste erfolgreiche Fall etwas weniger Zeit in Anspruch nehmen als die Summe aller Timeouts.

Gibt es eine Möglichkeit, dieses Timeout-Muster zu verbessern?

Ich habe überlegt, eine Methode mit delegate-Parametern und lock zu erstellen, um so etwas wie Linq-Verkettung zu erreichen (aber auch Sperren parallel auszuführen, ist eine Herausforderung):

Lock(lockA).Lock(lockB).Lock(lockC).Run( () => ...);

Oder vielleicht gibt es einen anderen Weg?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage