BackgroundWorker这个控件的用处?

xisimao 2009-06-05 01:58:18
1.这个控件是不是创建一个单独的线程执行操作?
2.这个控件貌似只能开始和取消,不能暂停吧?
3.这个控件能满足下面四个问题么?
谢谢指教
那么线程相关的问题大致有如下四类(这篇文章只讨论单线程、单线程与UI线程这两方面的问题)。

问题一,线程的基本操作,例如:暂停、继续、停止等;

问题二,如何向线程传递参数或者从中得到其返回值;

问题三,如何使线程所占用的CPU不要老是百分之百;

最后一个,也是问题最多的,就是如何在子线程来控制UI中的控件,换句话说,就是在线程中控制窗体某些控件的显示。

...全文
408 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lextm 2009-06-17
  • 打赏
  • 举报
回复
http://lextm.blogspot.com/2007/04/threading-or-pause-ready.html
可以使用ManualResetEvent来实现。
CFZC 2009-06-08
  • 打赏
  • 举报
回复
Mark!!
wisejohn 2009-06-07
  • 打赏
  • 举报
回复
Mark!
txg92 2009-06-07
  • 打赏
  • 举报
回复
backgroundWorker常用于解决后台一个费时的操作导致前台线程阻塞,UI假死的现象发生。采用backgroundWorker可以解决UI假死的现实,而且比较方便,简单的使用
xisimao 2009-06-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lextm 的回复:]
问题一,线程的基本操作,例如:暂停、继续、停止等;

*暂停没有直接的函数,但是使用一些同步信号就可以实现暂停。这个和普通线程是一样的。即使你指的是普通线程的暂停函数,那个函数已经废弃了,微软还是建议你使用同步信号的方式来暂停。

[/Quote]
楼上能详细说说么,使用一些同步信号是什么意思呢?求教!
lextm 2009-06-06
  • 打赏
  • 举报
回复
问题一,线程的基本操作,例如:暂停、继续、停止等;

*暂停没有直接的函数,但是使用一些同步信号就可以实现暂停。这个和普通线程是一样的。即使你指的是普通线程的暂停函数,那个函数已经废弃了,微软还是建议你使用同步信号的方式来暂停。

问题二,如何向线程传递参数或者从中得到其返回值;

*RunWorkerAsync函数是可以接受参数的。你传的参数都可以在DoWork里面从事件参数的Argument里面拿到的。至于返回值,你可以在DoWork里面设到事件参数的Result里面。这样在RunWorkerCompleted事件里面你就可以通过事件参数的Result使用这个返回值了。

问题三,如何使线程所占用的CPU不要老是百分之百;

*你一定要写死循环的话,没有什么办法不出100%。这个纯粹是编码问题,跟用不用这个控件无关。

最后一个,也是问题最多的,就是如何在子线程来控制UI中的控件,换句话说,就是在线程中控制窗体某些控件的显示。

*没什么特别的。一种是你在窗体里面定义一些本来就可以跨线程使用的方法,封装对于UI控件的修改。但是我推荐的是计划好你到底需要怎么修改控件,把它们都很好的对应到窗体的状态。这样只需要在DoWork中呼叫ReportProgress函数传递一个代表状态的整数值出来。然后在ProgressChanged事件里面根据这个状态值修改界面控件的状态就好了。

wuyq11 2009-06-06
  • 打赏
  • 举报
回复
backgroundWorker1.CancelAsync() 用于取消异步执行
backgroundWorker1.ReportProgress(int ,object)用于向主线层报告进度
backgroundWorker1.RunWorkerAsync():用于开始执行异步操作
backgroundWorker1.IsBusy 后台是否会执行
backgroundWorker1.WorkerReportsProgress 声明异步执行时是否可以报告进度
backgroundWorker1.WorkerSupportsCancellation 声明是否可以异步取消
backgroundWorker1.CancellationPending 是否取消异步执行
[url=http://www.cnblogs.com/lexus/archive/2008/08/27/1277956.html]参考[/url]
参考

xisimao 2009-06-05
  • 打赏
  • 举报
回复
up
linlusheng 2009-06-05
  • 打赏
  • 举报
回复
普通情况下,你点击一个按钮,去后台执行一个process,如果你想得到结果,就得等这个process结束。通常,可以使用异步执行回调来解决这个问题。现在,backgroundworker给我们实现了这样一种简单的封装,可以把我们的复杂任务交给新的线程去处理,然后继续UI线程。等到我们的任务需要通知UI做什么事情的时候,可以report一下,在其事件里就可以直接使用UI控件,而不需要Control.Invoke去掉用之。


有这样一个应用:客户需要把大量数据(需要执行3天)copy到另外一个机器,中间想能看到有多少数据被复制/失败等(实时报道)。

在这个例子里面,我们的界面可能非常简单:一个开始按钮,一个结束按钮,一个richtextBox来显示运行记录。但是后台执行可能就会比较棘手。如果简单的执行,并且报告,那么整个界面将失去响应(都在同一个线程里面,造成忙碌)。这时候,可以使用这个backgroundworker了。它可以在后台执行,并且报告给界面实时信息,界面不会失去响应。

先介绍一下backgroundworker的几个属性/方法

.WorkerReportsProgress:是否可以向外报告进度。

.WorkerSupportsCancellation :是否可以暂停任务

. CancellationPending: 是否正在暂停中

. RunWorkerAsync() : 开始执行任务。触发DoWork事件

. ReportProgress(int percentPrgress,object userState) : 向外报告进度。触发ProgressChanged事件.其中,参数可以在ProgressChangedEventArgs(worker_ProgressChanged(object sender, ProgressChangedEventArgs e))中得到

. CancelAsync() :取消(暂停)执行。

事件

worker.DoWork += new DoWorkEventHandler(worker_DoWork);//执行任务

worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);//任务结束时

worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged)//报告状态



按照上边的资料,我们这个应用就可以这样处理之

formDisplay是用于显示实时状态的窗口。有DisplyMessage方法来显示信息到界面

在Hanlder类(处理文件copy的)里面:

static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

//show the message on windows

formDisplay.DisplyMessage(“copy”, e.UserState.ToString());//show message.

}

static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

string msg = "JOB copy : have been completed";

formDisplay.DisplyMessage(msg);//show message

}



static void worker_DoWork(object sender, DoWorkEventArgs e)

{

for(…)

{

//copying

(sender as BackgroundWorker). ReportProgress(0,”xxx complete”);//report

}

}

这样构造的程序里面,才不会出现UI失去响应。

当然,通过写自己的异步处理也可以实现,功能更强大。只不过这个用起来更简单。

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧