zoukankan      html  css  js  c++  java
  • 黄聪:BackGroundWorker解决“线程间操作无效: 从不是创建控件的线程访问它” (C# VS2008)

    在编程中经常会遇到在一个按钮中执行复杂操作,并将复杂操作最后返回的值加入一个ListView或ComboBox中候选。这个时候程序会卡,当程序员将这些卡代码放进线程(Thread)中后发现当对控件操作时出现“线程间操作无效: 从不是创建控件的线程访问它”异常。
            为什么.net不让我们跨线程操作控件,这是有好处的。因为如果你的线程多了,那么当两个线程同时尝试将一个控件变为自己需要的状态时, 线程的死锁就会发生。但是难道就是因为这个原因,我们就只能让程序卡着么?当然不是,这里教大家一个解决方案:用BackGroundWorker
            这里通过一个实例来告诉大家BackGroundWorker的用法。
            首先我们先定义一个BackGroundWorker,大家可以去面板上拖一个,也可以自己手工定义一个。
    this.backgroundWorker_Combo = new System.ComponentModel.BackgroundWorker();//定义一个backGroundWorker
    this.backgroundWorker_Combo.WorkerSupportsCancellation = true;//设置能否取消任务
      this.backgroundWorker_Combo.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_Combo_DoWork);//让backgroundWorker做的事
    this.backgroundWorker_Combo.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_Combo_RunWorkerCompleted);//当backgroundWorker做完后发生的事件
            如果是从面板上拖的,那么请在DoWork事件上双击,添加那些你想在背景线程中执行的代码,也就是那些可能会让你卡的代码。
            然后再在RunWorkerCompleted事件上双击,添加那些你想往控件里操作的代码。
            这里有一个开发实例,讲的是实现类似Google搜索中下拉列表的实现。其思路是在DoWork中搜索数据库,在Completed中将搜出来的东西放进去。
            本文需要一个backgroundWorker,一个ComboBox控件
            static char x;
            
    /**//// <summary>
            
    /// 接受从DLL搜出来的项目
            
    /// </summary>

            private string[] global_ListItem;

            
    private void backgroundWorker_Combo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            
    {//如果数组中有东西,那么加入ComboBox
                if (global_ListItem.Length>0)
                
    {
                    
    this.comboBox_App.Items.Clear();
                    
    this.comboBox_App.Items.AddRange(global_ListItem);
                }

            }


            
    private void backgroundWorker_Combo_DoWork(object sender, DoWorkEventArgs e)
            
    {
                global_ListItem 
    = Form_Setting.Global_DBC.SimilarFilter(x); //这是一个DLL中的方法,用于查找所有以X打头的项目,并放入一个数组中
            }


            
    private void comboBox_App_TextChanged(object sender, EventArgs e)
            
    {//当用户键入一个字母时去数据库查
                ComboBox cb = sender as ComboBox;
                
    if (cb.Text.Length==1)
                
    {
                    x 
    = cb.Text[0];
                    
    this.backgroundWorker_Combo.RunWorkerAsync();
                }

            }

    第二种简单的方法是运用CheckForIllegalCrossThreadCalls,在主窗体的构造函数中加上  Control.CheckForIllegalCrossThreadCalls = false; 即可

  • 相关阅读:
    POJ 1300 Open Door
    POJ 2230 Watchcow
    codevs 1028 花店橱窗布置
    codevs 1021 玛丽卡
    codevs 1519 过路费
    codevs 3287 货车运输
    codevs 3305 水果姐逛水果街二
    codevs 1036 商务旅行
    codevs 4605 LCA
    POJ 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/huangcong/p/2004167.html
Copyright © 2011-2022 走看看