您的位置:首页 > 其它

关于线程间的控件互操作

2010-11-15 09:12 190 查看
当一个线程对另一个线程进行直接操作时,会提示“线程操作无效...”错误,原因是一个线程对另一个线程直接操作可能会出异常。

解决办法:

1、取消这个错误提示的办法,在form构造函数中添加CheckForIllegalCrossThreadCalls = false语句,则提示错误消失。但不提倡这种方法。

public Form1()
{
InitializeComponent();
//CheckForIllegalCrossThreadCalls = false;
}


2、控件有一个方法是安全操作控件的,该方法具体介绍如下所示(从C#网络编程 马骏编著中摘取,感谢马骏先生)

在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个InvalidOperationException异常,并提示消息:“从不是创建控件的线程访问它”。
但是在Windows应用程序中,为了在窗体上显示线程中处理的信息,我们可能需要经常在一个线程中引用另一个线程中的窗体控件。比较常用的办法之一是使用委托(delegate)来完成这个工作。 为了区别是否是创建控件的线程访问该控件对象,Windows应用程序中的每一个控件对象都有一个InvokeRequired属性,用于检查是否需要通过调用Invoke方法完成其他线程对该控件的操作,如果该属性为true,说明是其他线程操作该控件,这时可以创建一个委托实例,然后调用控件对象的Invoke方法,并传入需要的参数完成相应操作,否则可以直接对该控件对象进行操作,从而保证了安全代码下线程间的互操作。例如:
delegate void AppendStringDelegate(string str); private void AppendString(string str) { if (richTextBox1.InvokeRequired)
{ AppendStringDelegate d = new AppendStringDelegate(AppendString); richTextBox1.Invoke(d, "abc");
} else { richTextBox1.Text += str; }
}
这段代码中,首先判断是否需要通过委托调用对richTextBox1的操作,如果需要,则创建一个委托实例,并传入需要的参数完成else代码块的功能;否则直接执行else代码块中的内容。 实际上,由于我们在编写程序时就已经知道控件是在哪个线程中创建的,因此也可以在不是创建控件的线程中直接调用控件对象的Invoke方法完成对该线程中的控件的操作。 注意,不论是否判断InvokeRequired属性,委托中参数的个数和类型必须与传递给委托的方法需要的参数个数和类型完全相同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐