Частные переменные в задачах .net 4.0 - PullRequest
7 голосов
/ 14 июля 2011

немного экспериментирую, чтобы выяснить, как все работает. У меня есть следующий код ...

 for (int i = 0; i < 20; i++)
 {
      Task.Factory.StartNew(() => MethodTest(i));
 }

Мне интересно, почему MethodTest почти всегда получает int 20 (если я не перехожу в отладчик).

Очевидно, что в моем понимании чего-то не хватает, так как я предполагал, что когда передано 'i', оно будет частью локального хранилища управляемого потока.

1 Ответ

15 голосов
/ 14 июля 2011

Вы закрываете переменную цикла - попробуйте это:

 for (int i = 0; i < 20; i++)
 {
      int x = i;
      Task.Factory.StartNew(() => MethodTest(x));
 }

Важно понимать, что вы создаете замыкание над переменной i, а не является ее текущим значением .

Ко времени, когда пул потоков запускает первый поток (они сначала попадают в очередь), переменная i почти наверняка будет равна 20, поскольку вы вышли из цикла. Теперь каждый запущенный поток будет смотреть на значение переменной i в тот момент времени .

Исправление в соответствии с предложением заключается в создании новой переменной внутри области видимости цикла и назначении текущей переменной i этой переменной. Так как новая переменная используется на каждой итерации цикла, каждый созданный поток теперь закрывает свою «собственную» переменную, которая изолирована и не изменится.

Стандартная ссылка, объясняющая, что происходит: « Закрытие по переменной цикла, считающейся вредной ».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...