Блокировка по тайм-ауту

lock использует этот шаблон

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

если мы не хотим ждать бесконечно, мы можем предоставить тайм-аут

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

У меня есть сценарий, когда метод должен получить несколько блокировок, прежде чем начать что-либо делать. Это выглядит ужасно:

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

У него есть проблемы:

выглядит некрасиво (код метода с отступом, представьте, как он будет выглядетьlockZ), можно решить, поместив код метода в другой метод.

Блокировка происходит синхронно, поэтому наихудший успешный случай может занять немного меньше суммы всех таймаутов.

Есть ли способ улучшить этот тайм-аут?

Я думал создать метод с параметром делегата и блокировкой для достижения чего-то вроде цепочки linq (но также и для параллельной работы блокировок это сложная задача):

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

Или, может быть, есть другой способ?

Ответы на вопрос(1)

Ваш ответ на вопрос