zoukankan      html  css  js  c++  java
  • 线程间操作无效: 从不是创建控件的线程访问它的三种方法

    转自:https://www.cnblogs.com/luckboy/archive/2010/12/19/1910785.html

    今天遇到这个问题,百度了下,把解决的方法总结出来。
    我们在ui线程创建的子线程操作ui控件时,系统提示错误详细信息为:
    线程间操作无效: 从不是创建控件“XXX”的线程访问它

    就我知道的有三种方法,先看一下msdn的介绍:

    访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。

    看下解决办法吧

    1、把CheckForIllegalCrossThreadCalls设置为false

    2、利用委托

    delegate void SetTextCallBack(string text);
            private void SetText(string text)
            {
                if (this.txt_a.InvokeRequired)
                {
                    SetTextCallBack stcb = new SetTextCallBack(SetText);
                    this.Invoke(stcb , new object[] { text});
                }
                else
                {
                    this.txt_a.Text = text;
                }
            }
     
            private void LoadData()
            {
                SetText("测试");
            }
     
     
            //窗体加载时,用线程加载数据
            private void Frm_ImportManager_Load(object sender, EventArgs e)
            {
                ThreadStart ts = new ThreadStart(LoadData);
                Thread thread = new Thread(ts);
                thread.Name = "LoadData";
                thread.Start();
            }

    3、使用 BackgroundWorker控件

    在应用程序中实现多线程的首选方式是使用 BackgroundWorker 组件。BackgroundWorker 组件使用事件驱动模型实现多线程。辅助线程运行 DoWork 事件处理程序,创建控件的线程运行 ProgressChanged 和 RunWorkerCompleted 事件处理程序。注意不要从 DoWork 事件处理程序调用您的任何控件。

    下面的代码示例不异步执行任何工作,因此没有 DoWork 事件处理程序的实现。TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。

    // This event handler starts the form's 
            // BackgroundWorker by calling RunWorkerAsync.
            //
            // The Text property of the TextBox control is set
            // when the BackgroundWorker raises the RunWorkerCompleted
            // event.
            private void setTextBackgroundWorkerBtn_Click(
                object sender, 
                EventArgs e)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }
            
            // This event handler sets the Text property of the TextBox
            // control. It is called on the thread that created the 
            // TextBox control, so the call is thread-safe.
            //
            // BackgroundWorker is the preferred way to perform asynchronous
            // operations.
    
            private void backgroundWorker1_RunWorkerCompleted(
                object sender, 
                RunWorkerCompletedEventArgs e)
            {
                this.textBox1.Text = 
                    "This text was set safely by BackgroundWorker.";
            }

    大家可以参考下MSDN:
    如何:对 Windows 窗体控件进行线程安全调用

    http://msdn.microsoft.com/zh-cn/visualc/ms171728(VS.85,printer).aspx

  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/lichuangblog/p/8983808.html
Copyright © 2011-2022 走看看