频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

13.4.3.2 使用线程来实现闹钟功能

作者: 周礼 出处:清华大学出版社  2008-06-18 16:06    砖    好    评论   进入论坛
阅读提示:《C#和.NET 3.0第一步》第13章讲解C#多线程操作的相关内容。这一节说的是使用线程来实现闹钟功能。

13.4.3.2  使用线程来实现闹钟功能

使用线程来完成上面的闹钟功能也并不麻烦,你去掉上面的Timer控件,将Form类改为下面代码即可:

public partial class Form1 : Form
{
Thread threadClock;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.threadClock = new Thread(new ThreadStart(Timer_Tick));
//this.threadClock.IsBackground = true;
this.threadClock.Start();
}
private void Timer_Tick()
{
//Label lblClock = new Label();
//this.Controls.Add(lblClock);
while (true)
{
DateTime t = DateTime.Now;
lblClock.Font = new Font("宋体", 15);
lblClock.Text = t.ToString();
//8点1分1秒叫你起床
if (t.Hour == 8 && t.Minute==1 && t.Second == 1)
{
MessageBox.Show("懒猪,该起床了!");
}
Thread.Sleep(1000);
}

}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
this.threadClock.Abort();
}
}

上面的例子运行后效果和使用Timer控件一模一样,要注意代码中注释掉的部分。其中,在窗体加载方法中注释掉了this.threadClock.IsBackground一行代码,该行代码可以将当前线程设置为后台线程。我们提倡在Windows窗体程序中使用后台线程来做一些操作,原因是后台线程在主程序退出时可以自动关闭,如果使用前台线程你必须在窗体结束时自己关闭线程,很多人会忘记这步操作。另外,在线程对应的Timer_Tick方法中我们注释掉了如下两行代码:

Label lblClock = new Label();
this.Controls.Add(lblClock);

这两行代码是在线程里创建Label控件,你如果想使用这两行代码,你需要先把窗体中的Label控件删掉或改名。一旦你删掉窗体中的Label控件,使用这两行代码创建控件,在调试运行时会出现下面异常(图13.5):

 
图13.5  控件调用异常

这个异常是this.Controls.Add方法触发的,说你不能在创建控件之外的线程访问该控件。这个问题我们在介绍Windows窗体控件时并没有介绍,事实上,问题在于Windows窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个Invoke方法来将调用封送到适当的线程。Invoke方法属于控件基类Control的一个方法,用于在拥有此控件的窗口线程上执行指定的委托,使用起来比较麻烦。如上面例子,如果你真想使用线程来生成Label控件和调用Controls的Add方法,那么应该改为下面代码:

public partial class Form1 : Form
{
Thread threadClock;
//定义Invoke方法使用的委托
private delegate void UpdateTextDelegate();
......
private void Timer_Tick()
{
Runtime_UpdateUI();/*调用Invoke方法的方法*/
while (true)
{

}
    }
private void Runtime_UpdateUI()
{
//假如需要调用Invoke方法
if (this.InvokeRequired)
{
UpdateTextDelegate update =
new UpdateTextDelegate(this.Runtime_UpdateUI);
this.Invoke(update);
}
else
{
Label lblClock = new Label();
this.Controls.Add(lblClock);
}
}
}

上面代码中省略的部分和原来一样。在这里,我们为窗体类新添加了一个UpdateTextDelegate委托,该委托是提供给Invoke方法使用的。在调用Invoke方法时使用了InvokeRequired属性来判断当前情况下需不需要使用Invoke方法,此属性的使用可以保证该方法的兼容性,因为有可能本线程的其他方法也需要调用此方法,此时就不需要Invoke方法。要注意Invoke使用的委托还可能带有参数,此时你需要使用下面方式调用带参数的委托:

private void Runtime_SetMessage(string msg)
{
UpdateTextDelegate update = new UpdateTextDelegate(this.Runtime_SetMessage);
object[] args = new object[1] { msg };
if (this.txtBox.InvokeRequired)
{
//调用带参数的委托,使用object对象数组作为参数
this. txtBox.Invoke(update, args);
}
else
{
this. txtBox.Text = msg;
}
}

关于线程操作Windows窗体的内容我们就介绍到这里。一句话,你可以在窗体中为大量占用资源的任务使用多线程,这样可以保证窗体的正常响应(你可以尝试一下不用线程或Timer来实现上面那个闹钟的例子,可以依靠窗体的刷新事件Paint来实现,你会发现窗体不能正常响应)。另外,如果你在线程中想调用窗体控件的方法不要忘了使用Invoke方法。

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节
专题
Windows Home Server 家用服务器专题
程序员如何成长?
Windows Server 2008专题
windows网络安全指南
赛门铁克诺顿误杀Windows系统文件 导致百万系统崩溃
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
技术人求职简历完备手册
技术人求职简历完备手册
开源虚拟化技术Xen
开源虚拟化技术Xen
Windows Server 2008专题
Windows Server 2008专题
· Windows Server 2008专..
· 隐私保护技术探讨
· 绿色IT人健康生存手册
· 网络工程师职业规划与..
· 杀毒软件评测专题
· 访问控制列表(ACL)介绍
· Vista SP1对决XP SP3
· 华为员工自杀频频拷问..
· 2008中国互联网大会
· 微软出价446亿美元收购..
· 勇闯IT培训黑色围城
· CISSP认证成长之路
· 解析35岁技术人的价值..
· LAMP技术精解
· AMD Phenom三核处理器..
· 充电计划之热门IT认证..
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SOA 面向服务架构
SOA 面向服务架构
· SOA 面向服务架构
· SQL Server 2008/2005..
· Apache技术专题
· 三层交换技术专题
· SQL Server入门到精通
· Apache技术专题
· 国际文档格式标准开战
· 路由器设置与口令恢复
· PHP开发应用手册
· SOA 面向服务架构
· 企业数据恢复指南
· 了解统一威胁管理(UTM)..
· 专题:AIX操作系统管理..
· 访问控制列表(ACL)介绍
· 反垃圾邮件技术应用
· ASP.NET 2.0基础开发指..
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SQL Server入门到精通
SQL Server入门到精通
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· Apache技术专题
· 三层交换技术专题
· Apache技术专题
· 企业数据恢复指南
· 路由器设置与口令恢复
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· 反垃圾邮件技术应用
· 访问控制列表(ACL)介绍
· PHP开发应用手册
· 专题:AIX操作系统管理..
· 交换机故障解决指南
· 三层交换技术专题