我有一个场景。(Windows 窗体、C#、.NET)
- 有一个主窗体承载一些用户控件。
- 用户控件执行一些繁重的数据操作,因此如果我直接调用该
UserControl_Load
方法,UI 在加载方法执行期间将变得无响应。 - 为了克服这个问题,我在不同的线程上加载数据(尝试尽可能少地更改现有代码)
- 我使用了一个后台工作线程,它将加载数据,完成后将通知应用程序它已完成工作。
- 现在出现了一个真正的问题。所有 UI(主窗体及其子用户控件)都是在主主线程上创建的。在用户控件的 LOAD 方法中,我根据用户控件上的某些控件(如文本框)的值来获取数据。
伪代码如下所示:
代码 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 行 if 条件的执行。加载任务再次由父线程完成,而不是我产生的第三个。
我不知道我认为这是对还是错。我是线程新手。
我该如何解决这个问题以及执行 Line#1 if block 的效果是什么?
情况是这样的:我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我永远不会从子线程中执行此操作。
所以只有访问该值,以便可以从数据库中获取相应的数据。