lock
utilizza questo schemabloccaggio con il modello timeout
if(Monitor.Enter(lock))
try
{
...
}
finally { Monitor.Exit(lock); } // using this style to reduce post "height"
se non vogliamo aspettare all'infinito possiamo fornire timeout
if(!Monitor.TryEnter(lock, timeout))
throw new TimeoutException();
try
{
...
}
finally { Monitor.Exit(lock); }
ho scenario in cui il metodo deve ottenere serrature multiple prima di esso inizia a fare qualsiasi cosa Questo sembra terribile:
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); }
Ha problemi:
sembra brutto (il codice del metodo è rientrato, immaginare come sarà sguardi per
lockZ
), può essere risolto mettendo codice del metodo in un altro metodo .il blocco si verifica in modo sincrono, quindi il caso peggiore potrebbe richiedere del tempo leggermente inferiore alla somma di tutti i timeout.
C'è un modo per migliorare questo schema di timeout?
Stavo pensando di fare un metodo con il parametro delegato e di blocco per realizzare qualcosa di simile LINQ concatenamento (ma per eseguire anche le serrature in parallelo, questa è una sfida):
Lock(lockA).Lock(lockB).Lock(lockC).Run(() => ...);
O forse c'è un altro modo ?
Il blocco di Ctor è sicuramente uno schema ben distribuito, specialmente in C++. Si chiama RAII. –