Metodo # 1:
Il metodo più semplice e meno efficiente è quello di creare una sezione critica per i lettori e scrittori.
// Writer
lock (aList)
{
aList.Remove(item);
}
// Reader
lock (aList)
{
foreach (T name in aList)
{
name.doSomething();
}
}
Metodo # 2:
Questo è simile al metodo # 1, ma invece di tenere il blocco per tutta la durata del ciclo foreach
si dovrebbe copiare la raccolta e poi iterare il copia.
// Writer
lock (aList)
{
aList.Remove(item);
}
// Reader
List<T> copy;
lock (aList)
{
copy = new List<T>(aList);
}
foreach (T name in copy)
{
name.doSomething();
}
Metodo # 3:
Tutto dipende dalla vostra situazione specifica, ma il modo in cui io di solito affrontare questo è quello di mantenere il riferimento principale per la raccolta immutabile. In questo modo non dovrai mai sincronizzare l'accesso dal lato del lettore. Il lato scrittore delle cose ha bisogno di un lock
. Il lato lettore non ha bisogno di nulla, il che significa che i lettori rimangono altamente concomitanti. L'unica cosa che devi fare è contrassegnare il riferimento aList
come volatile
.
// Variable declaration
object lockref = new object();
volatile List<T> aList = new List<T>();
// Writer
lock (lockref)
{
var copy = new List<T>(aList);
copy.Remove(item);
aList = copy;
}
// Reader
List<T> local = aList;
foreach (T name in local)
{
name.doSomething();
}
fonte
2012-04-04 20:01:06
Grazie, funziona come un fascino :) Speriamo che non sarà possibile ottenere qualsiasi problemi di prestazioni utilizzando quello .. –