Переменная параметр backgroundWorker всегда одинакова?
У меня есть следующий код:
// 1.
public void RunSQL(QuerySetup querySetup)
{
//querySetup.Users is 10
for (int i = 1; i <= querySetup.Users; i++)
{
querySetup.CurrentUser = i;
var worker = new BackgroundWorker {WorkerReportsProgress = true};
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(querySetup);
}
}
// 2.
void worker_DoWork(object sender, DoWorkEventArgs e)
{
var querySetup = e.Argument as QuerySetup;
// Doing stuff...
e.Result = querySetup.CurrentUser;
}
// 3.
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("User " + e.Result.ToString() + " is done.");
}
Моя цель состоит в том, чтобы в конце я получил:
Пользователь 1 сделан
Пользователь 2 сделан
...
Пользователь 10 сделан
(не в этом конкретном порядке)
Но я получаю только 10х "Пользователь 10 готов".
Но почему? Мне нужно как-то пометить мой рабочий процесс, чтобы я мог идентифицировать его позже.
3 ответа
Да, здесь есть только 1 объект querySetup, и основной цикл будет постоянно менять currentUser.
Все потоки будут совместно использовать этот единственный объект.
for (int i = 1; i <= querySetup.Users; i++)
{
querySetup.CurrentUser = i;
...
worker.RunWorkerAsync(querySetup);
}
Основное решение (если вам не нужны другие члены querySetup)
for (int i = 1; i <= querySetup.Users; i++)
{
//querySetup.CurrentUser = i;
...
worker.RunWorkerAsync(i);
}
Существует только один экземпляр QuerySetup.
Вы сохраняете текущего пользователя в этом одном экземпляре. Таким образом, текущий пользователь всегда будет последним в вашем цикле.
Если все ваши работники закончат работу после завершения цикла, то все они увидят одно и то же глобальное состояние querySetup.CurrentUser
, что 10 в этот момент.
Наилучший подход к многопоточности - не разделять состояние между потоками (потому что это заставляет вас синхронизировать доступ к этому состоянию), а вместо этого предоставлять каждой функции потока свою собственную копию данных. В этом случае это будет означать, что вместо предоставления querySetup
В качестве данных для функции потока вы предоставляете querySetup.CurrentUser