2010-07-20 32 views

回答

14

使用BackgroundWorker的​​方法报告进度并订阅BackgroundWorker的ProgessChangedEvent以更新GUI中的进度。

您的副本类知道BackgroundWorker并订阅ProgressChanged。它还暴露了由事件处理程序为后台工作人员的ProgressChanged事件引发的自己的ProgressChanged事件。最后,您的Form订阅副本类的ProgressChanged事件并显示进度。

代码:

public class CopySomethingAsync 
{ 
    private BackgroundWorker _BackgroundWorker; 
    public event ProgressChangedEventHandler ProgressChanged; 

    public CopySomethingAsync() 
    { 
     // [...] create background worker, subscribe DoWork and RunWorkerCompleted 
     _BackgroundWorker.ProgressChanged += HandleProgressChanged; 
    } 

    private void HandleProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     if (ProgressChanged != null) 
      ProgressChanged.Invoke(this, e); 
    } 
} 

在您的形式只是订阅ProgressChanged事件的CopySomethingAsync和显示进度。

+0

您会如何将ProgressChanged事件暴露给窗体? – Martijn 2010-07-20 13:01:05

+0

我刚刚更新了我的答案以表明这一点。 – andyp 2010-07-20 13:25:01

+0

这是一个绝妙有用的答案,非常感谢! – 2011-01-12 15:42:50

8

一切。

,因为它说的文章:

要接收进度更新的通知,处理ProgressChanged事件。


更新:

读过的Martijn的补充问题,因为他有一类迄今一直在做他的工作,想必对前台线程,我想补充以下内容:

  • 工人阶级负责工作,所以它也有责任报告工作进展。它产生一个后台线程来完成这项工作的事实并不是Form的关注点。

  • 所以,我倾向于设置BGW类,并处理它的ProgressChanged事件,然后引发自己的事件(在前台线程上),然后表单本身就可以订阅它们。我使用这种技术做了大量的WinForms编码,它工作正常。

另一种方法是将BGW作为工人类的公共属性公开,并让表单直接处理其事件。但我不喜欢这么多,因为它使窗体依赖于工人类的实现。这通常是一件坏事。

+0

所以我要在增加公共背景属性我类和窗体必须注册到progresschanged事件? – Martijn 2010-07-20 12:45:10

2

它通过您当前的BackgroundWorker对象的ReportProgress实例方法完成。您的表单必须订阅ProgressChanged活动。

MSDN这里有一个小例子:http://msdn.microsoft.com/en-us/library/waw3xexc%28v=VS.100%29.aspx

+0

我的表单如何订阅ProgressChanged事件? – Martijn 2010-07-20 13:01:59

+0

'backgroundWorker1.ProgressChanged + = new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);'其中'backgroundWorker1_ProgressChanged'是您的事件处理方法的名称,由代理'ProgressChangedEventHandler'原型。 – Andreas 2010-07-20 13:05:49

+0

我不明白,对不起。我仍然没有看到我的表单可以注册到“ProgressChanged”事件。在你的情况下,有一个方法('backgroundWorker1_ProgressChanged')处理事件。但是我的表格需要处理这个事件,而不是我的班级。 – Martijn 2010-07-20 13:12:57

1

呼叫类

backgroundWorker.ReportProgress(i++); 

上的表单处理事件

//declare progressBar1 in the form and set range 
// progressBar1.Minimum = 0; 
//progressBar1.Maximum = 100; 
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     //show progress bar 

    } 
+0

在这种情况下,我如何在我的类中公开ProgressChanged事件? – Martijn 2010-07-20 12:46:29

+0

我只是给你的课一个BackgroundWorker的ProgressChanged事件引发的事件。您的活动将具有与BackgroundWorker相同的签名。 – andyp 2010-07-20 12:53:35

+0

您从传递的ProgressChangedEventArgs的ProgressPercentage实例字段(即progressBar1.Value = e.ProgressPercentage;)中获取传递给ReportProgress的值。 – Andreas 2010-07-20 12:55:58

相关问题