我如何等待BackgroundWorker的完成?

joe*_*975 1 .net wpf backgroundworker winforms

我想用它BackgroundWorker来从GUI执行数据库事务.

我如何命令BackgroundWorker执行工作然后等待工作人员完成,同时保持GUI响应?

我是否必须DoEvents为此目的使用,还是有另一种方式?

Rob*_*ney 10

询问"我如何命令BackgroundWorker执行工作,然后等待工作人员完成,同时保持GUI响应?" 真的在问"我该如何使用BackgroundWorker?".那是什么BackgroundWorker .

当你编写后台任务时,你基本上将方法分为四个部分:

  1. 准备好运行任务.
  2. 任务本身.
  3. 在任务运行时向UI报告进度.
  4. 任务完成后清理.

所以你需要编写四种方法.首先是创建一个方法BackgroundWorker,增加了事件处理程序的DoWork,ProgressChangedRunWorkerCompleted事件,使用户界面到任何状态它需要在任务运行时,并呼吁RunWorkerAsync启动任务.

其他三个是那三个事件处理程序. DoWork是一个DoWorkEventHandler完成工作的人,ReportProgress只要需要向UI报告进度,就会调用它. ProgressChangedProgressChangedEventHandler时,实际上是更新UI ReportProgress被调用.并且RunWorkerCompleted是一个RunWorkerCompletedEventHandler告诉UI工作完成的.

这里的所有都是它的.

好吧,不是全部.首先,您必须确保Error在完成处理程序中检查并处理该属性.如果你不这样做,你将无法知道你的do-work方法引发异常,因为它没有在UI线程中发生,因此不会引发你可以看到的异常.(它会显示在"输出"窗口中,如果您正在寻找它.)

其次,你必须确保DoWorkEventHandler它不会触及UI中的任何内容.如果您正在使用MVVM模式并且您没有计划这种偶然性,这可能会很棘手,因为通过数据绑定的魔力,您可能在模型中有更新UI绑定的视图的东西,这意味着在do-work方法操作模型正在操纵UI.假设您正在实现INotifyPropertyChanged,避免麻烦的一个好方法是构建一种机制,PropertyChanged在后台任务运行时,您的视图不会引发事件.

您还需要确定在任务运行时应禁用哪些UI部分.这取决于您的UI.答案可能是"全部",也可能不是.使用模态表单使您的进度指示器具有吸引力的一个原因是它可以让您免于解决这个问题,因为在模态表单打开时您的整个UI都被禁用了.如果您在启动方法中禁用控件或关闭属性更改通知,则需要在完成方法中重新打开.

请记住:UI的活动部分对数据模型所做的任何更新都是跨线程数据访问错误的潜在来源.如果您的UI和后台线程更新同一个对象,则会发生错误 - 如果您未Error在完成处理程序中处理该属性,则它们会特别糟糕,并且跨线程异常会在您不知情的情况下终止后台任务.如果这听起来像我在谈论这个,那是因为我在这个特殊的事情上错了很多时间.