Bloqueio com padrão de tempo limite

lock usa esse padrão

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

se não queremos esperar infinito, podemos fornecer tempo limite

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

Eu tenho cenário quando o método tem que obter vários bloqueios antes de começar a fazer qualquer coisa. Isso parece horrível:

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

Tem problemas:

parece feio (o código do método é recuado, imagine como ele ficarálockZ), pode ser resolvido colocando o código do método em outro método.

o bloqueio ocorre de forma síncrona, portanto, o pior caso de sucesso pode levar um tempo um pouco menos que a soma de todos os tempos limites.

Existe uma maneira de melhorar esse padrão de tempo limite?

Eu estava pensando em criar um método com parâmetro delegate e lock para obter algo como linq encadeamento (mas também executar bloqueios em paralelo, este é um desafio):

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

Ou talvez haja outro caminho?

questionAnswers(1)

yourAnswerToTheQuestion