版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、多线程编程(4):多线程与UI操作版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 HYPERLINK :/zhoufoxcn.blog.51cto /792419/267495 t _blank 原始出处 、作者信息和本声明。否则将追究法律责任。 HYPERLINK :/zhoufoxcn.blog.51cto /792419/267495 转自51cto专家博客 作者:周金桥为了让程序尽快响应用户操作,在开发Windows应用程序时经常会使用到线程。对于耗时的操作如果不使用线程将会是UI界面长时间处于停滞状态,这种情况是用户非常不愿意看到的,在这种情况下我们希望使用线程来解决
2、这个问题。下面是一个使用多线程操作界面UI的代码:using System; using System.Collections.Generic; using System ponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadPoolDemo public partial class ThreadForm : Form public ThreadForm() Initi
3、alizeComponent(); private void btnThread_Click(object sender, EventArgs e) Thread thread = new Thread(new ThreadStart(Run); thread.Start(); private void Run() while (progressBar.Value progressBar.Maximum) progressBar.PerformStep(); 程序的界面如下:我们的本意是点击“启动”按钮来启动模拟一个操作,在进度条中显示操作的总体进度。不过如果我们真的点击“启动”按钮会很失望,
4、因为它会抛出一个System.InvalidOperationException异常,异常描述就是“线程间操作无效: 从不是创建控件progressBar的线程访问它。”CheckForIllegalCrossThreadCalls属性之所以会出现这样的情况是因为在.NET中做了限制,不允许在调试环境下使用线程访问并非它自己创建的UI控件,这么做可能是怕在多线程环境下对界面控件进行操作会出现不可预知的情况,如果开发者可以确认自己的代码操作界面不会出现问题,可以用比较简单的方法解决,那就是设置CheckForIllegalCrossThreadCalls这个静态属性,它默认是true,如果将其设
5、为false的话,以后在多线程环境下操作界面也不会抛出异常了,我们上面的代码可以修改为:using System; usingneric; using System ponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadPoolDemo public partial class ThreadForm : Form public ThreadForm() Initiali
6、zeComponent(); private void btnThread_Click(object sender, EventArgs e) Thread thread = new Thread(new ThreadStart(Run); thread.Start(); private void Run() while (progressBar.Value progressBar.Maximum) progressBar.PerformStep(); 这样再执行程序就不会抛出异常了。不过使用上面的代码我们可能还有些犯嘀咕,毕竟是不允许直接在线程中直接操作界面的,那么我们还可以用Invoke方
7、法。Invoke方法来操作界面下面是一个例子:using System; using System.Collections.Generic; using System ponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadPoolDemo public partial class ThreadForm : Form /定义deleg
8、ate以便Invoke时使用 private delegate void SetProgressBarValue(int value); public ThreadForm() InitializeComponent(); private void btnThread_Click(object sender, EventArgs e) progressBar.Value = 0; /指示是否对错误线程的调用,即是否允许在创建UI的线程之外访问线程 /CheckForIllegalCrossThreadCalls = false; Thread thread = new Thread(new T
9、hreadStart(Run); thread.Start(); /使用线程来直接设置进度条 private void Run() while (progressBar.Value progressBar.Maximum) progressBar.PerformStep(); private void btnInvoke_Click(object sender, EventArgs e) progressBar.Value = 0; Thread thread = new Thread(new ThreadStart(RunWithInvoke); thread.Start(); /使用Inv
10、oke方法来设置进度条 private void RunWithInvoke() int value = progressBar.Value; while (value progressBar.Maximum) /如果是跨线程调用 if (InvokeRequired) this.Invoke(new SetProgressBarValue(SetProgressValue), value+); else progressBar.Value = +value; /跟SetProgressBarValue委托相匹配的方法 private void SetProgressValue(int val
11、ue) progressBar.Value = value; 这个方法的功能跟上面的操作是一样的,只不过不需要设置CheckForIllegalCrossThreadCalls属性,而且还不会抛出异常,当然除了上面的方法之外,还可以使用BackgroundWorker类来完成同样的功能。BackgroundWorker类操作界面因为使用BackgroundWorker类操作UI界面的例子周公博客上已经有过例子,所以这里的例子代码注释比较简单,读者可以看周公以前的示例,这次所使用的代码示例如下:using System; using System.Collections.Generic; usi
12、ng System ponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadPoolDemo public partial class ThreadForm : Form /定义delegate以便Invoke时使用 private delegate void SetProgressBarValue(int value); publi
13、c ThreadForm() InitializeComponent(); private void btnThread_Click(object sender, EventArgs e) progressBar.Value = 0; /指示是否对错误线程的调用,即是否允许在创建UI的线程之外访问线程 /CheckForIllegalCrossThreadCalls = false; Thread thread = new Thread(new ThreadStart(Run); thread.Start(); /使用线程来直接设置进度条 private void Run() while (p
14、rogressBar.Value progressBar.Maximum) progressBar.PerformStep(); private void btnInvoke_Click(object sender, EventArgs e) progressBar.Value = 0; Thread thread = new Thread(new ThreadStart(RunWithInvoke); thread.Start(); /使用Invoke方法来设置进度条 private void RunWithInvoke() int value = progressBar.Value; wh
15、ile (value progressBar.Maximum) /如果是跨线程调用 if (InvokeRequired) this.Invoke(new SetProgressBarValue(SetProgressValue), value+); else progressBar.Value = +value; /跟SetProgressBarValue委托相匹配的方法 private void SetProgressValue(int value) progressBar.Value = value; 当然,除了BackgroundWorker可以完成上面的功能之外,利用System.W
16、indows.Forms.Timer类也能完场上面的功能,代码如下:using System; using System.Collections.Generic; using System ponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadPoolDemo public partial class ThreadForm : Fo
17、rm /定义delegate以便Invoke时使用 private delegate void SetProgressBarValue(int value); private BackgroundWorker worker; public ThreadForm() InitializeComponent(); private void btnThread_Click(object sender, EventArgs e) progressBar.Value = 0; /指示是否对错误线程的调用,即是否允许在创建UI的线程之外访问线程 /CheckForIllegalCrossThreadCal
18、ls = false; Thread thread = new Thread(new ThreadStart(Run); thread.Start(); /使用线程来直接设置进度条 private void Run() while (progressBar.Value progressBar.Maximum) progressBar.PerformStep(); private void btnInvoke_Click(object sender, EventArgs e) progressBar.Value = 0; Thread thread = new Thread(new Thread
19、Start(RunWithInvoke); thread.Start(); /使用Invoke方法来设置进度条 private void RunWithInvoke() int value = progressBar.Value; while (value progressBar.Maximum) /如果是跨线程调用 if (InvokeRequired) this.Invoke(new SetProgressBarValue(SetProgressValue), value+); else progressBar.Value = +value; /跟SetProgressBarValue委托
20、相匹配的方法 private void SetProgressValue(int value) progressBar.Value = value; private void btnBackgroundWorker_Click(object sender, EventArgs e) progressBar.Value = 0; worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(worker_DoWork); /当工作进度发生变化时执行的事件处理方法 worker.ProgressChanged +=
21、 new ProgressChangedEventHandler(worker_ProgressChanged); /当事件处理完毕后执行的方法 worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); worker.WorkerReportsProgress = true;/支持报告进度更新 worker.WorkerSupportsCancellation = false;/不支持异步取消 worker.RunWorkerAsync();/启动执行 btnBackg
22、roundWorker.Enabled = false; /当事件处理完毕后执行的方法 void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) btnBackgroundWorker.Enabled=true; /当工作进度发生变化时执行的事件处理方法 void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) /可以在这个方法中与界面进行通讯 progressBar.Value = e.ProgressPercentage; /开始启动工作时执行的事件处理方法 void worker_DoWork(object sender, DoWorkEventArgs e) int value = progressBar.Value; while (valu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 疼痛管理与护理干预
- 教学《分数的再认识》数学课件教案
- 供货协议书范文
- 企业员工爱岗敬业演讲稿集合15篇
- 《超高层建筑风环境模拟与建筑外形优化设计的结构性能研究》教学研究课题报告
- 《金融科技推动下银行网点智能化转型的信息安全保障研究》教学研究课题报告
- 数据库性能测试工程师面试要点
- 会计岗位面试题集财务基础与实务操作
- 2025陕西建设机械有限责任公司招聘(101人)笔试参考题库附带答案详解(3卷)
- 2025重庆市设计院有限公司招聘29人笔试参考题库附带答案详解(3卷合一版)
- 2025年山西大地环境投资控股有限公司社会招聘116人备考题库有答案详解
- 2026元旦主题晚会倒计时快闪
- 物理试卷答案浙江省9+1高中联盟2025学年第一学期高三年级期中考试(11.19-11.21)
- 2025年交管12123学法减分考试题附含答案
- 俄语口语课件
- 2025广西自然资源职业技术学院下半年招聘工作人员150人(公共基础知识)综合能力测试题带答案解析
- django基于Hadoop的黑龙江旅游景点系统-论文11936字
- 2025-2026学年广东省深圳市福田中学高一(上)期中物理试卷(含答案)
- 口腔解剖生理学牙的一般知识-医学课件
- 施工现场安全、文明考核管理办法
- 香蕉购买协议书模板
评论
0/150
提交评论