新疆软件开发

本站首页 软件开发 成功案例 公司新闻 公司简介 客服中心 软件技术 网站建设
  您现在的位置: 新疆二域软件开发公司 >> .Net技术 >> 文章正文

教程:.Net多线程和Windows Forms编程

1 UI线程执行耗时操作  UI线程被阻塞 无法响应窗体消息队列中的其他消息。

2 非UI线程修改UI属性 由于窗体资源也属于临界资源 所以有互斥访问的机制。

3 线程的同步问题 线程A等待线程B执行完毕后才能开始执行。

问题1的解决方法:
解决方法只有一种,就是开启新线程执行耗时操作,使原界面线程仍能够响应窗体消息队列中的用户消息及系统消息。

开启新线程的方式有以下各种:
1) 使用System.Threading.Thread类与System.Threading.ThreadStart委托或System.Threading.ParameterizedThreadStart委托来实现开启新线程。
ThreadStart委托的类型: void ThreadStart(void);
ParameterizedThreadStart委托的类型: void ParameterizedThreadStart(object[]);

ThreadStart委托可以指向一个无参数无返回值的方法。
ParameterizedThreadStart委托可以指向一个有参数无返回值的方法。

Thread类实例化的时候可以向构造函数传入ThreadStart委托的实例或ParameterizedThreadStart委托的实例,然后使用Thread.Start()以异步方式调用一个方法。

2) 为需要异步执行的耗时方法定义一个委托,使用该委托的实例的BeginInvoke方法来异步调用该方法,BeginInvoke方法附带了AsyncCallback类型的回调函数委托以及object类型的参数。
然后可以在AsyncCallback类型的回调函数中使用EndInvoke方法来得到异步方法的返回值。

3) 可以使用System.Timers.Timer定时器类来实现在新线程中执行耗时操作,System.Timers.Timer定时器不同于System.Windows.Forms.Timer定时器,System.Timers.Timer定时器的定时事件的响应函数并不是在调用定时器Start方法的线程中去执行。

4) 可以使用BackgroundWorker组件来实现在新线程中执行耗时操作(通过订阅DoWork事件).


问题2的解决方法
以下代码是.NetFramework 2.0类库中避免多线程修改界面造成的临界资源死锁问题的代码。
System.Windows.Forms.Control.get_Handle方法的内部实现

public IntPtr get_Handle()
{
    if ((checkForIllegalCrossThreadCalls && !inCrossThreadSafeCall) && this.InvokeRequired)
    {
        throw new InvalidOperationException(SR.GetString("IllegalCrossThreadCall", new object[] { this.Name }));
    }
    if (!this.IsHandleCreated)
    {
        this.CreateHandle();
    }
    return this.HandleInternal;
}



在修改每个控件的属性的时候,都会先调用get_Handle方法获取一个操作句柄,在该方法内部会判断Control类的静态成员CheckForIllegalCrossThreadCalls的值(该成员用来表示是否启用安全模式,安全模式的意思就是禁止跨线程修改界面属性来避免多线程访问临界资源死锁的问题),第二个判断的属性是InvokeRequired属性(该属性用来表示当前方法是否是在跨线程调用)。 所以我们可以通过修改CheckForIllegalCrossThreadCalls属性为False来关闭安全模式,但有可能造成线程死锁问题。

解决方法只有两个
1) 设置CheckForIllegalCrossThreadCalls属性为False,关闭.net的安全模式,在对界面属性修改的代码加上lock,来实现同一时间仅有一个线程修改界面属性。
2) 在设置界面属性的方法中询问InvokeRequired属性,如果是非界面线程修改界面属性,则让界面线程来调用设置界面属性的方法。(这个方法是MSDN实例中惯用的方法,也是BackgroundWorker等组件的内部实现方式)


推荐大家使用BackgroundWorker来实现耗时操作的辅助线程以及跨线程修改界面属性等操作,关于BackgroundWorker的具体使用方法见 一日一练 之 BackgroundWorker

作者:未知 | 文章来源:自学编程网 | 更新时间:2007-12-29 12:38:59

  • 上一篇文章:

  • 下一篇文章:

  • 相关文章:
    j2se 嵌入式脚本抓取引擎
    NET Framework 2.0 Service Pack 2下载地址
    Java语言学习:jAVA中 的多线程浅析
    解析.NET中的6各大的安全错误
    java多线程SOCKET程序的问题
    .NET中Boolean,bool以及String,string之间的区别
    在VC 程序中自定义Vista事件日志
    .Net FrameWork 2.0 新增功能 Bulk Copy
    多线程技术在.net中是如何应用的
    C++函数对象count_if
    软件技术
    · 开发语言
    · Java技术
    · .Net技术
    · 数据库开发
    最新文章  
    ·.net技术 asp.net MVC3 Vi
    ·.net将视频文件格式转换成
    ·NET Framework 2.0 Servic
    ·如何动态修改winform的app
    ·asp,net软件结构设计和相关
    ·学习怎样使用ASP.NET中的虚
    ·,net基础类的学习:system
    ·.net学习:c#事件的深入分
    ·Facade Pattern学习总结
    ·C#如何设置或者获取目录的
    ·如何使用XSL来定义ASP.NET
    ·理解WCF Data Contract契约
    ·如何能在.net2.0开发的控件
    ·模式怎样使用,讲解模式的
    ·如何解决Menu菜单被frame遮
    关于我们 | 软件开发 | 下载试用 | 客服中心 | 联系我们 | 友情链接 | 网站地图 | 新疆电子地图 | RSS订阅
    版权所有 © 2016 新疆二域软件开发网 www.k8w.net All Rights Reserved 新ICP备14003571号
    新疆软件开发总机:0991-4842803、4811639.
    客服QQ:596589785 ;地址:新疆乌鲁木齐北京中路华联大厦A-5C 邮编:830000