Ho il seguente metodo:Perché C# non conserva il contesto per le chiamate anonime dei delegati?
static Random rr = new Random();
static void DoAction(Action a)
{
ThreadPool.QueueUserWorkItem(par =>
{
Thread.Sleep(rr.Next(200));
a.Invoke();
});
}
ora chiamare questo in un ciclo come questo:
for (int i = 0; i < 10; i++)
{
var x = i;
DoAction(() =>
{
Console.WriteLine(i); // scenario 1
//Console.WriteLine(x); // scenario 2
});
}
in scenario 1 dell'output sono: 10 10 10 10 ... 10
nello scenario 2 l'uscita è: 2 6 5 8 4 ... 0
(permutazione casuale da 0 a 9)
Come si spiega? C# non dovrebbe conservare le variabili (qui i
) per la chiamata anonima del delegato?
Ma preservando ('catturare') la * variabile * 'i' è * esattamente * cosa sta succedendo! Quello che * non * sta accadendo, sebbene tu lo voglia, sta preservando * il ** valore ** di 'i' nel momento in cui il delegato è impostato *. – AakashM
Incidentalmente, ReSharper ti avviserà di un [Accesso alla chiusura modificata] (http://confluence.jetbrains.net/display/ReSharper/Access+to+modified+closure) quando viene presentato con questo codice; potresti trovare la spiegazione utile. – AakashM
http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx –