public void GatherDataFromSwitches(Device[] switches)
{
List<Thread> workerThreads = new List<Thread>();
for(int i = 0; i < switches.Length - 1; i++)
{
Thread t = new Thread(unused => GatherDataFromSwitch(switches[i]));
workerThreads.Add(t);
t.Start();
}
foreach (Thread d in workerThreads) d.Join(); //wait for all threads to finish
}
Если я пройду через коммутаторы после запуска этого метода, я заметил, что каким-то образом некоторые коммутаторы не добавили данных, а некоторые коммутаторы имели данные, добавленные с нескольких коммутаторов. Так что что-то пошло не так с передачей ссылки на рабочие потоки. Я до сих пор не уверен, что именно, но я решил эту проблему, добавивC# - Создание нескольких потоков с использованием Lambda
Thread.Sleep(100);
сразу после
t.Start();
Я предполагаю, что это работает, потому что теперь вновь созданный поток имеет некоторое время для инициализации до того следующий будет создан. Но это работа, а не исправление. Это из-за того, как работают лямбда-выражения?
Как правильно обойти это?
Это действительно исправляет его, я первоначально начал с цикла foreach. Кажется странным копировать объект, чтобы передать его лямбда. –
@Maximiliaan Aelvoet: На самом деле, я предпочитаю вторую версию, которая делает более понятным, что вы передаете индекс в качестве параметра в поток. По крайней мере, для меня это более понятно, так как я начал программировать с помощью pthreads. :) Кстати, не забудьте отметить ответ, как принято, если он решит вашу проблему. – Tudor
Просто для объяснения: проблема с исходной версией заключалась в том, что lambda принимает значение 'i' в момент его фактического выполнения. Поскольку потоки, которые вы запускаете, запускаются асинхронно, нет способа узнать, какое значение будет иметь значение 'i', к тому времени, когда каждый поток достигнет кода, который использует' i'. – Tudor