原文: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();
}

WPF中的线程使用的更多相关文章

  1. 在 WPF 中的线程

    线程处理使程序能够执行并发处理,以便它可以做多个操作一次.节省开发人员从线程处理困难的方式,设计了 WPF (窗口演示文稿基金会).这篇文章可以帮助理解线程在 WPF 中的正确用法. WPF 内部线程 ...

  2. 线程在WPF中的使用

    项目中可能会有这样的需求,一直获取新的某个数据信息,但仍不影响其他的操作功能,这时就用到了线程,获取新数据放到线程中操作,对其他操作不产生影响,下面就以随机获取数组中项为例解说WPF中使用线程这一实例 ...

  3. WPF中窗口控件的跨线程调用

    在WinForm中,我们要跨线程访问窗口控件,只需要设置属性CheckForIllegalCrossThreadCalls = false;即可. 在WPF中要麻烦一下,同样的不允许跨线程访问,因为没 ...

  4. WPF非UI线程中调用App.Current.MainWindow.Dispatcher提示其他线程拥有此对象,无权使用。

    大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(ne ...

  5. WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)

    原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...

  6. 将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)

    原文:将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本) 如果你要在 WPF 程序中使用线程池完成一个特殊的任务,那么使用 .NET 的 API Task.Run 并传入一个 L ...

  7. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  8. 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?

    源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...

  9. WinForm与WPF下跨线程调用控件

    Winform下: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText( ...

随机推荐

  1. March 31 2017 Week 13 Friday

    Sometimes, you think the sky is falling down, actually, that is just because you stand slanting. 有时候 ...

  2. 另一种方式实现事务码SE16里的结果集修改

    注: 这种方法不同于网上流传的在调试器里修改fcode的那种解决方案. 使用场景:我们需要直接在开发系统的事务码SE16里修改某些结果集的值,但是在SE16的工具栏里看不见修改按钮: 解决方案 使用/ ...

  3. POJ 2985 名次树

    题意:1~n个猫,有合并操作,有询问操作,合并两只猫所在的集合,询问第K大的集合. 分析:合并操作用并查集,用size维护,询问操作用Treap.注意优化,不能刚开始就把所有size = 1放到名次树 ...

  4. Swift学习——格式控制符和元组流程控制(二)

    Swift中的格式控制符和元祖 (1)首先介绍一下元祖,元祖是关系型数据库中  比如学生表中的姓名,年龄,电话等 定义例如以下 var studentinfo = ("jhon", ...

  5. 2018.11.26 struts2流程源码

    struts2的架构图 从最上面的类开始,也就是i 我们的核心过滤器strutsPrepareAndExecuteFilter 判断当前请求是否由struts2来处理,如果是就往else走,不由它来处 ...

  6. WSASocket()与Socket()的区别 转

    /**************************************************** WSASocket是Windows专用,支持异步操作:socket是unix标准,只能同步操 ...

  7. Storm 中drpc调用

    package storm.starter; import backtype.storm.Config; import backtype.storm.LocalCluster; import back ...

  8. 总结的MR中连接操作

    1 reduce side join在map端加上标记, 在reduce容器保存,然后作笛卡尔积缺点: 有可能oom 2 map side join  2.1 利用内存和分布式缓存,也有oom风险 2 ...

  9. C#解析HTML神器 Html Agility Pack

    曾经,我傻乎乎的用正则表达式成功的解析了学校的新闻网.教务管理系统.图书馆管理系统中我想要的所有的内容.那时候废了好大的劲写那正则啊,而且最后还是各种不给力,经常会有意想不到的bug出现,最后经过无数 ...

  10. 【Linux-CentOS】【转-更正】使用CentOS DVD1 和DVD2做本地yum源

    原文在此.此文写的非常好,怕网络丢失,特转来,并做了更正. CentOS6以上版本一般都会提供一个DVD1和一个DVD2镜像,使用DVD1即可安装使用CentOS了,DVD2中存放了一些额外的软件包, ...