转载:https://www.cnblogs.com/atskyline/archive/2012/06/22/2558516.htmlhtml
简介
但凡涉及到图形界面,每每的设计都是不支持或者不推荐使用多个线程操做界面内容.并且一般会有一个专门的线程调度器来处理任务线程和界面线程的问题.下面提供两个两个方案.c#
使用Dispatcher.BeginInvoke
这个方法简单暴力适合小工做量的修改一些界面内容.使用Dispatcher.BeginInvoke()会将代码安排为调度程序的一个任务.异步
步骤函数
- 使用Thread新建并开始一个线程
- 在新建的线程处理函数中须要修改界面的时候获取界面的dispatcher
- 使用Dispatcher的BeginInvoke方法指定一个线程优先级,和一个委托,这个委托时用于修改界面内容的
下面给出一部分代码this
//新建线程 Thread thread = new Thread(UpdateTextRight); thread.Start();
下面是新线程中的方法spa
//这个事例恰好是先窗体类中定义的,因此获取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()启动.因此在这个事件中不要去处理修改界面的事情code
RunWorkerCompleted事件,在DoWork事件返回时(正常或者异常返回),在图形的线程中执行,因此能够修改界面orm
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(); }