笔者在写c#窗体项目时候,碰到了线程间操作无效: 从不是创建控件的线程访问它这个异常。
这个异常得原因就是:
访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
出错的情形:
所以在某个窗体代码中在主进程之外又开启了一个线程,去访问或者修改任何不是该线程创建的控件属性、方法的时候,就会报这个错。
例如:
public partial class test1 : SkinMain { public test1() { InitializeComponent(); init(); } public void init() { //创建一个新线程 Thread m_thread = new Thread(ThreadFun); m_thread.Start(); } private void ThreadFun() { //这就是不是用创建控件的线程访问它,所以运行到这里就会报错 panel10.name="test"; } }
或者是,你直接把当前的窗体控件传给其他类调用访问修改控件的时候也会报这个错。
例如:
public partial class test1 : SkinMain
{
public test1()
{
InitializeComponent();
init();
}
public void init()
{
//传参调用其他类访问或修改控件,
test2 t=new test2();
t.modity(this.panel10);
}
}
解决办法:
1:直接在构造函数代码中加入(不推荐)
//解决线程间操作无效: 从不是创建控件的线程访问它
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
2:使用委托
把代码改成这样:
public partial class test1 : SkinMain
{
public test1()
{
InitializeComponent();
init();
}
public void init()
{
//使用委托
ThreadFunDelegate threadFunDelegate = new ThreadFunDelegate(ThreadFun);
threadFunDelegate.Invoke();
}
//声明委托线程,解决线程间操作无效: 从不是创建控件的线程访问它
public delegate void ThreadFunDelegate();
private void ThreadFun()
{
//正常运行
panel10.name="test";
}
}