Существует общее правило, согласно которому не обновляйте пользовательский интерфейс из какого-либо потока, кроме самого потока пользовательского интерфейса. Использование функций BackgroundWorker - хорошая идея, но вы не хотите, чтобы что-то происходило в другом потоке, вы должны выполнить «Invoke» или BeginInvoke, чтобы заставить делегата выполнить метод в потоке пользовательского интерфейса.
Редактировать: Джон Б высказал это замечание в комментариях:
Имейте в виду, что Invoke ()
синхронный и BeginInvoke () является
асинхронный. Если вы используете Invoke (), вы
должны быть осторожны, чтобы не вызвать
тупиковый. Я бы посоветовал
BeginInvoke (), если вам действительно не нужно
вызов должен быть синхронным.
Простой пример кода:
// Updates the textbox text.
private void UpdateText(string text)
{
// Set the textbox text.
m_TextBox.Text = text;
}
public delegate void UpdateTextCallback(string text);
// Then from your thread you can call this...
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText),
new object[]{"Text generated on non-UI thread."});
Приведенный выше код взят из часто задаваемых вопросов об этом здесь и более длинном, более сложном здесь .