我有一个场景。(Windows窗体,C#、. NET)
UserControl_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行。加载任务再次由父线程完成,而不是我产生的第三个任务。
我不知道我是对是错。我是线程新手。
我该如何解决这个问题,如果执行第1行的代码阻塞还会产生什么影响?
情况是这样的 :我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我永远不会从子线程执行此操作。
因此,仅访问该值,以便可以从数据库中获取相应的数据。
根据Prerak K的更新评论(已删除):
我想我没有正确提出问题。 情况是这样的:我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我永远不会从子线程执行此操作。 因此,仅访问该值,以便可以从数据库中获取相应的数据。
我想我没有正确提出问题。
情况是这样的:我想根据控件的值将数据加载到全局变量中。我不想从子线程更改控件的值。我永远不会从子线程执行此操作。
您想要的解决方案应如下所示:
UserContrl1_LOadDataMethod() { string name = ""; if(textbox1.InvokeRequired) { textbox1.Invoke(new MethodInvoker(delegate { name = textbox1.text; })); } if(name == "MyName") { // do whatever } }
在 尝试切换回控件的线程 之前, 请在单独的线程中 进行 认真的处理。例如:
UserContrl1_LOadDataMethod() { if(textbox1.text=="MyName") //<<======Now it wont give exception** { //Load data correspondin to "MyName" //Populate a globale variable List<string> which will be //bound to grid at some later stage if(InvokeRequired) { // after we've done all the processing, this.Invoke(new MethodInvoker(delegate { // load the control with the appropriate data })); return; } } }