У меня есть сценарий. (Windows Forms, C #, .NET)
- Существует основная форма, которая содержит некоторый пользовательский элемент управления.
- Пользовательский элемент управления выполняет некоторую сложную операцию с данными, так что, если я напрямую вызываю
UserControl_Load
метод, пользовательский интерфейс перестает отвечать на запросы при выполнении метода загрузки. - Чтобы преодолеть это, я загружаю данные в другой поток (пытаясь как можно меньше изменить существующий код)
- Я использовал фоновый рабочий поток, который будет загружать данные и когда это будет сделано, уведомит приложение о том, что оно выполнило свою работу.
- Теперь появилась настоящая проблема. Весь пользовательский интерфейс (основная форма и ее дочерние элементы управления) был создан в основном основном потоке. В методе LOAD пользовательского контроля я выбираю данные, основанные на значениях некоторого элемента управления (например, текстового поля) в userControl.
Псевдокод будет выглядеть так:
КОД 1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
Это исключение было
Недопустимая операция между потоками: доступ к элементу управления из потока, отличного от потока, в котором он был создан.
Чтобы узнать больше об этом, я немного погуглил, и пришло предложение, например, с использованием следующего кода
Код 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
НО НО ... кажется, я вернулся к исходной точке. Приложение снова перестает отвечать на запросы. Кажется, это связано с выполнением строки # 1, если условие. Задача загрузки снова выполняется родительским потоком, а не третьим, который я породил.
Я не знаю, понял ли я это правильно или неправильно. Я новичок в потоке.
Как мне решить это, а также каков эффект выполнения строки # 1, если блок?
Ситуация такова : я хочу загрузить данные в глобальную переменную на основе значения элемента управления. Я не хочу менять значение элемента управления из дочернего потока. Я не собираюсь делать это когда-либо из детской ветки.
Так что доступ только к значению, так что соответствующие данные могут быть получены из базы данных.