C#线程间操作无效:从不是创建控件“textbox1”的线程访问它
创始人
2024-02-21 14:45:40
0

  在C#的多线程访问中,在线程间的相互访问时因为线程安全问题有访问限制,在创建一般线程时,对于界面元素访问时这样的问题比较常见。

  比如,创建一个form1,上面放置一个textbox控件,创建一个线程去访问textbox,界面如下:

  按钮buuton1的代码:

        private void button1_Click(object sender, EventArgs e){var thread1 = new System.Threading.Thread(Func1);thread1.Start();}

  就是简单地创建一个线程,线程里面运行的func1代码:

        private void Func1(){for(int i = 0; i < 5; i++){textBox1.Text = textBox1.Text+ $"线程{Thread.CurrentThread.ManagedThreadId}执行{i}."+Environment.NewLine;}}

  运行,点击button1按钮系统会报错:

  意思是说:线程间操作无效:从不是创建控件“textbox1”的线程访问它,这是不允许的。

  线程存在安全保护机制,并不能随意访问,因为这样存在冲突的可能。

  解决这个问题,最直接的方法是在界面初始化后去掉控件的跨线程非法访问属性,即将Control.CheckForIllegalCrossThreadCalls属性设置为false即可。

        public Form1(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false;}

  这样结果就出来了。

  一般情况下,还是不要设置Control.CheckForIllegalCrossThreadCalls的属性,那么怎样可以达到修改textbox1的值呢?

  可以通过委托来解决。

    public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){var thread1 = new System.Threading.Thread(Func1);thread1.Start();}public void SetText(string SText){textBox1.Text = textBox1.Text + SText + Environment.NewLine;}private void Func1(){string Str = "";for (int i = 0; i < 5; i++){Str= $"线程{Thread.CurrentThread.ManagedThreadId}执行{i}."+Environment.NewLine;if (textBox1.InvokeRequired){Action SetText111 = delegate { SetText(Str); };textBox1.Invoke(SetText111);}else{textBox1.Text = Str;}}}}

  这样也可以达到目的,或者直接写更简单:

    public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){var thread1 = new System.Threading.Thread(Func2);thread1.Start();}private void Func2(){textBox1.Invoke(() =>{for (int i = 0; i < 5; i++){textBox1.Text = textBox1.Text+ $"线程{Thread.CurrentThread.ManagedThreadId}执行{i}." + Environment.NewLine;}});}}

  效果也是一样的。

  在C#中,需要注意Invoke和begininvoke的区别。

  control.invoke(参数delegate):在拥有此控件的基础窗口句柄的线程上执行指定的委托,注意是同步。
  control.begininvoke(参数delegate):在创建控件的基础句柄所在线程上异步执行指定委托,注意这里执行的是异步。

  在跨线程请求时,常检验textBox1.InvokeRequired属性,即是否跨线程请求。

相关内容

热门资讯

上海知名拆迁律师机构推荐,诚信... 在上海,拆迁问题一直备受关注,选择一位靠谱的拆迁律师至关重要。知名的拆迁律师机构和诚信的拆迁专业律师...
老师诅咒全班得甲流 律师:违反... 大象新闻记者 姜明圆 “让他们全都甲流,赶紧滚回去。”近日,小学老师百人群内咒骂全班得甲流,引发网友...
甘其毛都司法所“中蒙桥”调解室... 近日,内蒙古巴彦淖尔市乌拉特中旗甘其毛都司法所以“一所一品”特色服务品牌创建为抓手,以“双语沟通、双...
沙坪坝区首家“社区法律诊所”开... “非独生子女家庭,把财产通过遗嘱方式全给儿子继承,违法吗?”“母亲的黄昏恋对象,需要我们来赡养吗?”...
桃源法院:柔性化解租赁合同纠纷... 近日,桃源县人民法院成功调解一起厂房租赁合同纠纷案件,既维护了原告桃源县某投资公司的合法权益,又为被...
重庆啤酒“山城往事”落幕,1亿... 蓝鲸新闻12月17日讯(记者 朱欣悦)重庆啤酒的“山城往事”终于要告一段落。 近日,重庆啤酒披露,与...
法治赋能促“绿叶”变“金叶”,... 12月16日,清远市人大常委会办公室举行《清远市促进英德红茶产业发展条例》颁布施行新闻发布会。据通报...
泽普县司法局开展矛盾纠纷化解暨... 12月15日,泽普县司法局在波斯喀木乡梧桐村,开展矛盾纠纷化解和法律援助宣讲活动。活动现场,工作人员...