黑马程序员技术交流社区
标题:
关于跨线程检查的问题
[打印本页]
作者:
mdb
时间:
2014-3-18 00:20
标题:
关于跨线程检查的问题
本帖最后由 mdb 于 2014-3-22 16:51 编辑
我们知道,当在一个新的线程里操作主线程上的控件时,会引发类似于“线程间操作无效: 从不是创建控件“textBox1”的线程访问它”的异常,当然我们可以在窗体的构造方法里设置CheckForIllegalCrossThreadCalls=false即可让程序不报这个异常提示。
修改CheckForIllegalCrossThreadCalls的属性会有什么副作用吗,如果不修改CheckForIllegalCrossThreadCalls属性,还有什么方法能让程序不引发线程间操作无效的异常?
作者:
cancle
时间:
2014-3-18 10:09
求涨姿势~~
作者:
shangxin
时间:
2014-3-18 11:45
CheckForIllegalCrossThreadCalls是Control的静态类,定义如下:
public static bool CheckForIllegalCrossThreadCalls { get; set; }
因此可以这么用:Control.CheckForIllegalCrossThreadCalls,又因为Form继承自Control,所以可以直接调用这个属性,一旦这个属性设置为False,所有控件都会共享这个属性
作者:
zhangcheng5468
时间:
2014-3-22 16:43
在WinForm或WPF中,默认只允许在创建控件的线程(一般为UI线程)中访问控件,如果我们想在子线程中访问UI线程的资源,需要做特殊处理
WinForm处理方式
WinForm当中,我们有两种方式来解决这个问题。我们可以在窗体构造函数当中添加CheckForIllegalCrossThreadCalls = false,禁止窗体进行非法跨线程调用的校验,只是屏蔽了非法校验,并没有真正解决问题,不推荐使用
我们可以使用一下方式解决WinForm中UI资源的跨线程调用问题
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() => ChangeText());
thread.Start();
}
private void ChangeText()
{
Random rdm = new Random();
string num = rdm.Next().ToString();
//当前线程是创建此控件的线程
if (txt.InvokeRequired)
txt.Invoke(new Action<string>(s => txt.Text = s), num);
//当前线程不是创建此控件的线程
else
txt.Text = num;
}
WPF程序的处理方式
每个WPF应用程序中都有一个Dispatcher类对象,该类对象是一个队列,用来保存应用程序主线程中的所有正在执行的工作。为了避免多个线程通过访问同一WPF控件的相同属性,其他线程应该请求主线程代表它执行访问控件属性的操作,即把访问主线程的方法放到主线程的Dispather类的对象中排队
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() => ChangeText());
thread.Start();
}
private void ChangeText()
{
Random rdm = new Random();
string num = rdm.Next().ToString();
//当前线程不是主线程
if (Dispatcher.Thread != Thread.CurrentThread)
{
Dispatcher.Invoke(new Action<string>(s => txt.Text = s), num);
}
//当前线程是主线程
else
txt.Text = num;
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2