Я считаю, что BackgroundWorker предназначен для автоматического использования нового потока. Поэтому создание нового потока просто для вызова RunWorkerAsync является излишним. Вы создаете поток, чтобы создать еще один поток. Что, вероятно, происходит, это:
- Вы создаете новый поток из потока 1 (поток с графическим интерфейсом); назовите эту тему 2.
- Из потока 2 вы запускаете RunWorkerAsync, который сам создает еще один поток; назовите эту тему 3.
- Код для RunWorkerCompleted выполняется в потоке 2, который является потоком с именем RunWorkerAsync.
- Поскольку поток 2 не совпадает с потоком GUI (поток 1), вы получаете недопустимое исключение вызова между потоками.
(В приведенном ниже предложении используется VB вместо C #, поскольку это то, с чем я более знаком; я полагаю, вы можете выяснить, как написать соответствующий код C #, чтобы сделать то же самое.)
избавиться от посторонней новой нити; просто объявите _worker WithEvents, добавьте обработчики в _worker.DoWork и _worker.RunWorkerCompleted, а затем вызовите _worker.RunWorkerAsync вместо определения пользовательской функции PerformWorkerTask.
РЕДАКТИРОВАТЬ : Чтобы обновить средства управления графическим интерфейсом в поточно-ориентированном режиме, используйте код, подобный следующему (более или менее скопированный из этой статьи из MSDN ):
delegate void SetTextCallback(System.Windows.Forms.Control c, string t);
private void SafeSetText(System.Windows.Forms.Control c, string t)
{
if (c.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SafeSetText);
d.Invoke(d, new object[] { c, t });
}
else
{
c.Text = t;
}
}