Я подозреваю, что они не становятся мертвыми - я подозреваю, что проблема в том, что вы на самом деле не соблюдаете те правила, о которых думаете. Когда вы используете локальные переменные метода в анонимном методе, сами переменные захватываются. В этом случае вы захватываете локальную переменную count
и затем изменяете ее (по мере уменьшения счетчика цикла). К тому времени, когда поток, созданный при count = 4, начинает работать, count
может быть 3 - поэтому он будет вызывать runRule[3].performTask(ru[3], ds[3], 3)
. На самом деле, count
может изменить во время вычисления выражений , что может доставить массу удовольствия.
Способ обойти это состоит в том, чтобы иметь разные «локальные» переменные для каждой итерации цикла. Это легко сделать:
Thread[] td = new Thread[5];
for (count = 4; count >= 0; --count)
{
int copy = count;
ds[count] = dba.getData(ru[count]);
td[count] = new Thread(delegate() {
runRule[copy].performTask(ru[copy], ds[copy], copy);
});
td[count].Name = "Thread " + count.ToString();
td[count].Start();
Thread.Sleep(50);
}
Теперь единственными переменными, фиксируемыми в делегате, являются copy
и runRule
/ ru
/ ds
- я предполагаю, что последние три не меняются. Новый «экземпляр» переменной copy
создается каждый раз, когда вы обходите цикл, поэтому изменения не будут мешать друг другу.
Посмотрите, поможет ли это - это по крайней мере потенциальная причина для массовой путаницы, и вполне может быть проблемой.