原文:WPF中的线程使用

简介

但凡涉及到图形界面,往往的设计都是不支持或者不推荐使用多个线程操作界面内容.而且通常会有一个专门的线程调度器来处理任务线程和界面线程的问题.下面提供两个两个方案.

使用Dispatcher.BeginInvoke

这个方法简单暴力适合小工作量的修改一些界面内容.使用Dispatcher.BeginInvoke()会将代码安排为调度程序的一个任务.

步骤

  1. 使用Thread新建并开始一个线程
  2. 在新建的线程处理函数中需要修改界面的时候获取界面的dispatcher
  3. 使用Dispatcher的BeginInvoke方法指定一个线程优先级,和一个委托,这个委托时用于修改界面内容的

下面给出一部分代码

//新建线程
Thread thread = new Thread(UpdateTextRight);
thread.Start();

下面是新线程中的方法

//这个事例刚好是先窗体类中定义的,所以获取Dispatcher变得比较方便,而且使用了匿名委托.在通常的代码中会把委托给分离出去比较好.
private void UpdateTextRight()
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart) delegate()
{
txt.Text = "Here is some new text.";
}
);
}

使用BackgroupWorker

这个类是专门用于简化Windows Form程序与线程相关的问题设计的,同样适用于WPF程序.适合于一个长期的后台进程,支持进度通知,取消支持,完成通知等功能.

使用方法也很简单,创建一个BackfruopWorker实例,它有几个事件.

DoWork事件会在另外一个线程中执行,用RunWorkerAsync()启动.所以在这个事件中不要去处理修改界面的事情

RunWorkerCompleted事件,在DoWork事件返回时(正常或者异常返回),在图形的线程中执行,所以可以修改界面

ProgressChanged事件,使用ReportProgress()方法调用,同时是在图形界面的线程中执行,通常负责修改一下进度条什么的.而ReportProgress()方法,通常会在DoWork的事件中调用,然后给一个百分比的值.要使用这个功能,需要把WorkerReportsProgress属性设置成true

另外值得一说的是,要取消支持需要把WorkerSupportsCancellation属性设为true,使用CancelAsync()方法调用,但是这个调用不会终止进程,所以在DoWork事件中需要判断CancellationPending.

下面给出部分代码

创建BackgroundWorker实例

BackgroundWorker backgroundWorker;
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; //可以返回工作进度
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; //允许取消
backgroundWorker.WorkerSupportsCancellation = true;

开始执行DoWork

backgroundWorker.RunWorkerAsync();

DoWork事件范例,这个方法的内容是在另外一个线程,异步执行得

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
while(!backgroundWorker.CancellationPending)
{
//Do SomeThing
//在合适的时候使用
//backgroundWorker.ReportProgress(i);
//报告一下进度,其中i是0-100的整数
}
//这里可以使用e.Result给一个返回值,如果有需要的话
}

进度改变时的处理事件,也就是修改一下进度条什么的

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}

完成事件我就不演示,下面是取消任务的方法

private void cmdCancel_Click(object sender, RoutedEventArgs e)
{
backgroundWorker.CancelAsync();
}

最新文章

  1. Atitti 大话存储读后感 attilax总结
  2. nodejs+edatagrid读取本地excel表格
  3. jsp如何自定义tag的标签库?
  4. Android——初探Dagger2依赖注入
  5. 混合式APP开发中中间件方案Rexsee
  6. RHEL7下PXE+NFS+Kickstart无人值守安装操作系统
  7. nignx开启expires后相关资源不显示的问题
  8. struts——文件上传
  9. 【一天一道LeetCode】#110. Balanced Binary Tree
  10. .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
  11. Java设计模式总结
  12. python之模块3
  13. 数据分析:基于Python的自定义文件格式转换系统
  14. 【原】 The Linux Command Line- pwd,cd,ls,file,less
  15. DateGridView标题列头添加复选框
  16. TCP粘包、拆包
  17. 技术课堂】如何管理MongoDB数据库?
  18. JMeter (3) —— JMeter录制脚本并压力测试用户登陆场景以CAS SSO为例(101 Tutorial)
  19. Bata验收互评
  20. <meta name="viewport" content="width=device-width, initial-scale=1.0">的说明

热门文章

  1. pymongo 常用操作函数
  2. IT人们给个建议
  3. 塔防cocos2d
  4. 一个有意思的标签<marquee>
  5. SQLite动态库下载
  6. getElementsByName和getElementById
  7. MySQL提升课程 全面讲解MySQL架构设计
  8. jquery mobile 移动web(4)
  9. Integer大小比较问题
  10. 『嗨威说』常见的C++函数模板整理(一)