跨线程操作无效:从创建该线程的线程以外的线程访问控件

陌路散爱 提交于 2020-08-07 09:44:14

问题:

I have a scenario. 我有一个场景。 (Windows Forms, C#, .NET) (Windows窗体,C#、. NET)

  1. There is a main form which hosts some user control. 有一个主窗体可以承载一些用户控件。
  2. The user control does some heavy data operation, such that if I directly call the UserControl_Load method the UI become nonresponsive for the duration for load method execution. 用户控件执行一些繁重的数据操作,因此,如果我直接调用UserControl_Load方法,则UI在加载方法执行期间将无响应。
  3. To overcome this I load data on different thread (trying to change existing code as little as I can) 为了克服这个问题,我将数据加载到不同的线程上(尝试尽我所能更改现有代码)
  4. I used a background worker thread which will be loading the data and when done will notify the application that it has done its work. 我使用了一个后台工作线程来加载数据,完成后将通知应用程序它已经完成了工作。
  5. Now came a real problem. 现在出现了一个真正的问题。 All the UI (main form and its child usercontrols) was created on the primary main thread. 所有UI(主窗体及其子用户控件)均在主主线程上创建。 In the LOAD method of the usercontrol I'm fetching data based on the values of some control (like textbox) on userControl. 在usercontrol的LOAD方法中,我基于userControl上某些控件(如文本框)的值获取数据。

The pseudocode would look like this: 伪代码如下所示:

CODE 1 代码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.
    }
}

The Exception it gave was 它给的例外是

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on. 跨线程操作无效:从创建该线程的线程以外的线程访问控件。

To know more about this I did some googling and a suggestion came up like using the following code 要了解更多信息,我进行了一些谷歌搜索,并提出了一条建议,例如使用以下代码

CODE 2 代码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
    }
}

BUT BUT BUT... it seems I'm back to square one. 但是但是...看来我又回到了正题。 The Application again become nonresponsive. 该应用程序再次变得无响应。 It seems to be due to the execution of line #1 if condition. 如果有条件,这似乎是由于执行了第1行。 The loading task is again done by the parent thread and not the third that I spawned. 加载任务再次由父线程完成,而不是我产生的第三个任务。

I don't know whether I perceived this right or wrong. 我不知道我是对是错。 I'm new to threading. 我是线程新手。

How do I resolve this and also what is the effect of execution of Line#1 if block? 我该如何解决这个问题,如果执行第1行的代码阻塞还会产生什么影响?

The situation is this : I want to load data into a global variable based on the value of a control. 情况是这样的 :我想根据控件的值将数据加载到全局变量中。 I don't want to change the value of a control from the child thread. 我不想从子线程更改控件的值。 I'm not going to do it ever from a child thread. 我永远不会从子线程执行此操作。

So only accessing the value so that the corresponding data can be fetched from the database. 因此,仅访问该值,以便可以从数据库中获取相应的数据。


解决方案:

参考一: https://stackoom.com/question/awN/跨线程操作无效-从创建该线程的线程以外的线程访问控件
参考二: https://oldbug.net/q/awN/Cross-thread-operation-not-valid-Control-accessed-from-a-thread-other-than-the-thread-it-was-created-on
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!