Это не имеет ничего общего с самими событиями, а скорее связано с тем, что вы обращаетесь к элементам управления пользовательского интерфейса из другого потока.В Windows Forms вам не разрешено взаимодействовать с пользовательским интерфейсом из какого-либо другого потока, кроме основного потока пользовательского интерфейса.
Вы можете использовать InvokeRequired
, чтобы проверить, находитесь ли вы в потоке, который не имеет доступа к пользовательскому интерфейсуи затем используйте Invoke
для запуска кода в потоке пользовательского интерфейса, если это необходимо.Это может выглядеть примерно так:
private void DoStuffWithGUI()
{
if (InvokeRequired)
{
Action work = DoStuffWithGUI;
Invoke(work);
}
else
{
// Your normal logic
}
}
Пользовательский интерфейс можно использовать непосредственно из ProgressChanged и RunWorkerCompletedEvents (поскольку они автоматически направляются в поток пользовательского интерфейса).Но вся работа, которую вы выполняете в DoWork (и, следовательно, все события, которые вы можете вызывать как часть работы), выполняется в отдельном потоке и должна быть направлена в поток пользовательского интерфейса с помощью Invoke.Из MSDN для BackgroundWorker :
Вы должны быть осторожны, чтобы не манипулировать объектами пользовательского интерфейса в обработчике событий DoWork.Вместо этого связывайтесь с пользовательским интерфейсом через события ProgressChanged и RunWorkerCompleted.