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

下面提供两个方案:

1、使用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.";
}
);
}

2、使用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 [调用线程无法访问此对象,因为另一个线程拥有该对象.] 解决方案以及如何实现字体颜色的渐变 先来看看C#中Timer的简单说明,你想必猜到实现需要用到Timer的相关知识了吧. C# ...

  2. WPF不同线程之间的控件的访问

    原文:WPF不同线程之间的控件的访问 WPF不同线程之间的控件是不同访问的,为了能够访问其他线程之间的控件,需要用Dispatcher.Invoke执行一个新的活动即可. 例如: public voi ...

  3. WPF的线程模型

    原文:WPF的线程模型 WPF的线程模型            周银辉 谈到多线程,很多人对其可能都不太有好感,觉得麻烦与易出错.所以我们不排除有这样的情况:假设我对“多线程”.“异步”这些字眼潜意识 ...

  4. WPF跨线程操作UI界面控件

       在WPF应用中,如果遇到多线程的需求时,如果引用WPF控件时会引发异常,异常内容:调用线程无法访问此对象,因为另一个线程拥有该对象.具体如下: 调用代码: ThreadcountThread= ...

  5. WPF 通过线程使用ProcessBar

    WPF下使用进度条也是非常方便的,如果直接采用循环然后给ProcessBar赋值,理论上是没有问题的,不过这样会卡主主UI线程,我们看到的效果等全部都结束循环后才出现最后的值. 所以需要采用线程或者后 ...

  6. WPF后台线程更新UI

    0.讲点废话 最近在做一个文件搜索的小软件,当文件多时,界面会出现假死的状况,于是乎想到另外开一个后台线程,更新界面上的ListView,但是却出现我下面的问题. 1.后台线程问题 2年前写过一个软件 ...

  7. WPF子线程更新UI(Dispatcher.BeginInvoke)

       在做WPF开发时,如果直接在子线程里更新UI会报错—–“调用线程无法访问此对象,因为另一个线程拥有该对象.”,这是因为WPF禁止在非UI线程里直接更新UI界面. 解决方案:   在子线程里调用D ...

  8. wpf 调用线程必须为sta 因为许多ui组件都需要

    解决 办法 public void SomeMethod() { var task = System.Windows.Application.Current.Dispatcher.BeginInvok ...

  9. wpf程序线程与UI内容交互

    在UI线程里执行复杂的操作,会造成UI假死.常用的解决方法是开2个线程. 而新线程要调用UI里的东西,必须这么用: this.Dispatcher.Invoke(content);

随机推荐

  1. eCryptfs文件系统测试

    650) this.width=650;" onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" ...

  2. Northwind数据库表字段介绍

    ① Categories:种类表 相应字段: CategoryID :类型ID: CategoryName:类型名; Description:类型说明; Picture:产品样本 ② Customer ...

  3. hdu5072-Coprime(容斥原理)

    题意:给N个互不相同的数,选择出两两互质或者两两不互质的三个数,有多少种选法. 题解:一共有C(N,3)中选择方式,减去不符合要求的,剩下的就是答案. 详见 http://blog.csdn.net/ ...

  4. 第三百四十九、五十天 how can I 坚持

    昨天是忘写博客了,今天下班才突然意思到,搞框架搞了好晚.今天重新下了个好了. 昨天,把存储过程交给同事写了,啥都不会,又一堆问题,折腾了一天. 今天相对轻松些,不过事情还没完..明天又周五了. 还有昨 ...

  5. Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱(转)

    原文:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开 ...

  6. Dependency Injection学习笔记

    component把需要依赖者(CoffeeMaker)和供应提供者(Heater, Pump)联系起来 使用 区别:上的的依赖是内部创建的,下面的依赖是外面传进来的 注入方式

  7. HDU 5861 Road (线段树)

    Road 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Description There are n villages alo ...

  8. Python输入输出(IO)

    程序会有输入和输出,输入可以从标准输入或是从一个文件读入数据,程序的输出可以以一种友好可读的方式(human-readable)打印出来,或是写进一个文件,而标准输入和标准输出(键盘和显示器)在程序的 ...

  9. 8.1搜索专练DFS和BFS

    这是第一次全部做出来的依次练习了,有一些都是做过两遍了的,但是还是错了几回,更多时候我还是应该多注意下细节,就好像章爷笑我 的一样,像什么vis[]标记没清0,什么格式错误,还有什么题目没看清,还是的 ...

  10. wikioi 1098 均分纸牌

    题目描述 Description 有 N 堆纸牌,编号分别为 1,2,-, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸 ...