winform下跨线程操作Control的一个坑

本文探讨了在WinForm应用中如何在不同线程间正确操作Control,尤其是针对AForge等第三方库的Control。文章指出,简单地禁用Control的非法跨线程检查可能无法解决所有问题,而必须使用委托方法。文中详细分析了`IsHandleCreated`和`InvokeRequired`属性的作用,并提供了正确的委托实现方式,以避免跨线程异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例如要在另一个线程里执行Test方法,改变form的标题

private void Form1_Load(object sender, EventArgs e)
{
	Thread t = new Thread(Test);
	t.Start();
}
public void Test(){
	this.Text="aaa";
}

winform下跨线程操作Control主要有两种方式,
1,偷懒的方式
直接把Control的检查合法跨线程的设置为false,不检查

Control.CheckForIllegalCrossThreadCalls = false;

但是,在面对一些封装好的Control,例如,视频播放的AForge(2.25版本)时,发现就算设置了

VideoSourcePlayer.CheckForIllegalCrossThreadCalls = false

也没用,而且vs2019居然不报错(太坑了)
目测是没有通过这个字段来检测是否合法跨线程
后来我写了try catch才发现的错误
“Cross thread access to the control is not allowed.”
问题出在AForge.Controls.VideoSourcePlayer.CheckForCrossThreadAccess()
看了源码

private void CheckForCrossThreadAccess()
{
	if (!base.IsHandleCreated)
	{
		CreateControl();
		if (!base.IsHandleCreated)
		{
			CreateHandle();
		}
	}
	if (base.InvokeRequired)
	{
		throw new InvalidOperationException("Cross thread access to the control is not allowed.");
	}
}

问题出在IsHandleCreated,和InvokeRequired
这两个都是只读的,分别是判断是否时form所在线程创造的,是否需要委托,
然后,只能使用委托的方式实现跨线程操作Control了,’
就有了另一个坑
委托的实现方式
Action的方式

public void Test(){
	new Action(Testt).BeginInvoke(null, null);
}
public void Testt(){
	this.Text="aa";
}

试了下,一样会报跨线程异常的问题
后来才发现,必须要使用Form的BeginInvoke,并且显示定义delegate才能起作用

public delegate void MyInvoke(); 
public void Test(){
	 MyInvoke mi = new MyInvoke(Testt);
     this.BeginInvoke(mi); //这里是关键
}

个人猜测是this.BeginInvoke同时也把this对象传递给了跨线程要执行的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值