彩票走势图

vs2005中解决不能跨线程调用控件问题

转帖|其它|编辑:郝浩|2010-09-20 11:03:58.000|阅读 806 次

概述:本文将介绍vs2005中解决不能跨线程调用控件问题,希望对大家有帮助。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  如果代码是在 VS2003中的话应该不会抛出这个异常,只有在使用VS2005的时候,如果你从非创建这个控件的线程中访问这个控件或者操作这个控件的话就会抛出这个异常。这是微软为了保证线程安全以及提高代码的效率所做的改进.

  以前在 VS2003中,我们通常都会忽略这种问题的存在,无限制的使用线程来完成一些工作,但是当系统慢慢变大的时候,这种滥用的线程不但没有提高我们的效率,反而使我们找错误的效率以及系统的复杂度大大的增加了。

  微软的这一改动可以让我们在使用线程的时候,充分考虑一下线程的安全以及线程的使用规范,这样会有益于我们做出健壮的程序。

      坚决这种跨线程的问题在 VS2005中提供了两种简单的方法(我个人当前所了解的只有这两种):
一种是通过设置 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;(winform 下)如果在你的程序初始化的时候设置了这个属性,而且在你的控件中使用的都是微软 Framework 类库中的控件的话,系统就不会再抛出你上面所说的这个错误了。当然这只是为了将 VS2003的代码转换到 VS2005下所使用的一种常见的方法。不建议采用。

  第二种方法就是微软建议采用的跨线程调用的一种通用方法,就是使用代理来实现,就是将你所要操作的代码放到一个代理种,然后将这个代理交给创建这个控件的线程来执行你的代码。例如:
private void Form1_Load(object sender, EventArgs e)
{
//创建线程需要 System.Threading 命名空间
Thread t1, t2; // 说明为窗体类成员
t1 = new Thread(new ThreadStart(BackgroundProcess));
t1.Start(); //启动线程t1
}
/// <summary>
/// 定义一个代理
/// </summary>
private delegate void dd();

private void BackgroundProcess()
{
// 将代理实例化为一个匿名代理
dd = delegate()
{
int i = 1;
while (true)
{
// 向列表框增加一个项目
listBox1.Items.Add("Iterations: " + i.ToString());


i++;
Thread.Sleep(2000); // 指定线程休眠的时间
}
};
listBox1.Invoke(dd);
}
上面这个代码只是在你的代码中声明了一个代理,并且用 VS2005中新加的语法(匿名代理,又名匿名方法。)来实例话这个代理,将你在线程中要操作的代码都放到这个匿名的方法中去。然后通过使用控件的 Invoke 方法(也可以使用控件的 BeginInvoke 方法——Invoke 方法是同步的 BeginInvoke 方法是异步的)来调用这个代理。当然在 Invoke 方法中你也可以输入任何形式的代理。通过这种方式调用的代码就不会抛出你出现的那个异常了。

  上面这种代理的方式类似于 C++中的回调函数,你写出了执行的方法,然后通知某个线程由那个线程来调用你的这个方法,这样就做到了在固定的线程里执行修改线程内部组件的方式。这样就完全达到线程安全了。

  另外,如果你使用的不是.NET 类库中的控件的话,最好不要使用第一种方式,因为某些第三方控件在线程安全性方面做的不是太好,可能还会抛出一些不可预料的异常。例如 DevExpress 控件库一般会抛出对象引用为空的异常。所以建议所有在 VS2005种使用线程操作控件的时候都利用第二种方法来实现,如果嫌麻烦,也可以将这些控件利用继承的方式在父类里面实现这些代理方式的修改。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP