Winform使用多线程操作控件出现“线程间操作无效: 从不是创建控件的线程访问它。”

问题:使用多线程操作控件出现“线程间操作无效: 从不是创建控件“comboBox1”的线程访问它。”
原因:微软因为安全原因不允许不是同一个线程中操作控件,只允许同一个线程或进程中操作。


解决:1.使用控件的Invoke()方法解决
           2.放入窗体的构造函数中,“InitializeComponent()”方法后执行

以下是使用控件Invoke()方法解决:

 public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        //问题:使用多线程操作控件出现“线程间操作无效: 从不是创建控件“comboBox1”的线程访问它。”
        //原因:微软因为安全原因不允许不是同一个线程中操作控件,只允许同一个线程或进程中操作。
        //解决:1.使用控件的Invoke方法解决
        //      2.放入窗体的构造函数中,“InitializeComponent()”方法后执行

        //Step 1: 定义委托
        delegate void SetComboxBoxCallback(List<DataModel> list);

        //Step 2: 定义更新UI控件方法
        private void AddDataToComboxBox(List<DataModel> list)
        {
            //InvokeRequired required compares the thread ID of the
            //calling thread to the thread ID of the creating thread. 
            //If these threads are different, it returns true.
            if (this.comboBox1.InvokeRequired)//如果调用控件的线程和创建创建控件的线程不是同一个则为True
            {
                while (!this.comboBox1.IsHandleCreated)
                {
                    //解决窗体关闭时出现“访问已释放句柄“的异常
                    if (this.comboBox1.Disposing || this.comboBox1.IsDisposed)
                        return;
                }
                SetComboxBoxCallback method = new SetComboxBoxCallback(AddDataToComboxBox);
                this.comboBox1.Invoke(method, new object[] { list });

                //绑定数据到指定DataGridView
                //this.dgv.Invoke(new EventHandler(delegate
                //{
                    //dgv.DataSource = list;
                //}));

                //绑定到多个控件
                //this.Invoke(new EventHandler(delegate
                //{
                    //cmbQuestionType.DataSource = list;
                    //cmbQuestionType1.DataSource = list;
                //}));
                

            }
            else
            {
                comboBox1.Items.AddRange(list.ToArray());
            }
        }

        //Step 3 定义异步执行方法
        private void SyncLoadComboxBox()
        {
            Task.Factory.StartNew(() =>
            {
                comboBox1.DisplayMember = "Name";
                comboBox1.ValueMember = "ID";
                comboBox1.Sorted = true;

                List<DataModel> dataList = new List<DataModel>();
                dataList.Add(new DataModel() { ID = 1, Name = "阿里巴巴" });
                dataList.Add(new DataModel() { ID = 2, Name = "腾讯" });
                dataList.Add(new DataModel() { ID = 3, Name = "百度" });
                dataList.Add(new DataModel() { ID = 4, Name = "华为" });
                AddDataToComboxBox(dataList);
            });
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            SyncLoadComboxBox();
        }
    }

    public class DataModel
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值