我有一个场景。(Windows窗体,C#、. NET)
- 有一个主窗体可以承载一些用户控件。
- 用户控件执行一些繁重的数据操作,因此,如果我直接调用该
UserControl_Load
方法,则UI将在装入方法执行期间无响应。 - 为了克服这个问题,我将数据加载到不同的线程上(尝试尽我所能更改现有代码)
- 我使用了一个后台工作线程来加载数据,完成后将通知应用程序它已经完成了工作。
- 现在出现了一个真正的问题。所有UI(主窗体及其子用户控件)均在主主线程上创建。在usercontrol的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行的代码阻塞还会产生什么影响?
情况是这个:我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我永远不会从子线程执行此操作。
因此,仅访问该值,以便可以从数据库中获取相应的数据。