У меня есть сценарий. (Windows Forms, С#,.NET)
- Существует основная форма, в которой размещается некоторый пользовательский элемент управления.
- Пользовательский элемент управления выполняет некоторую работу с тяжелыми данными, так что, если я непосредственно вызываю метод
UserControl_Load
, пользовательский интерфейс перестает отвечать на длительность выполнения метода загрузки. - Чтобы преодолеть это, я загружаю данные в разные потоки (пытаясь изменить существующий код как можно меньше)
- Я использовал фоновый рабочий поток, который будет загружать данные, и когда это будет сделано, уведомит приложение о том, что он выполнил свою работу.
- Теперь появилась настоящая проблема. Весь основной пользовательский интерфейс (основная форма и его дочерние пользовательские элементы управления) были созданы в основном основном потоке. В методе LOAD для usercontrol я извлекаю данные на основе значений некоторого элемента управления (например, текстового поля) в 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, если блок?
Ситуация такова:: я хочу загрузить данные в глобальную переменную на основе значения элемента управления. Я не хочу изменять значение элемента управления из дочернего потока. Я не собираюсь делать это из детской нити.
Таким образом, доступ к значению так, что соответствующие данные могут быть получены из базы данных.