后台工作人员从不同的班级更新(最好通过活动)

时间:2013-05-21 19:16:02

标签: c# winforms events backgroundworker

我的GUI类中有一个后台工作程序。

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    ProgressClass obj = new ProgressClass();
    Importer tradeImporter = e.Argument as Importer;
    BackgroundWorker worker = sender as BackgroundWorker;
    List<TradeUploadInfo> list = obj.AllocateTrades2(tradeImporter, false);
    e.Result = list; //Passes the list for processing
}

导入器是我自己的类。现在,AllocateTrades2方法已完成所有处理。

我的问题是,我如何在bw.ProgressReport方法中执行AllocateTrades2,该方法在不同的类中,而不将bw作为参数传递?

如果有人向我解释如何使用事件来解决这个问题会很棒,但如果还有另一种优雅方式的话。我很开心。

3 个答案:

答案 0 :(得分:5)

如果你不想传递整个BGW(理所当然地),以便不暴露超出它需要知道的内容,一个选择就是传入你指定{{1}的委托。致电。

ReportProgress的签名调整为:

AllocateTrades2

从该方法中适当地调用public List<TradeUploadInfo> AllocateTrades2( Importer importer, bool flag, Action<int> reportProgress) 委托。

然后将调用调整为reportProgress,如下所示:

AllocateTrades2

答案 1 :(得分:1)

好吧,鉴于AllocateTrades2在后​​台工作程序的上下文中运行,它所引发的任何事件也会在该上下文中执行。

因此,您需要做的就是在ProgressClass中添加一个新事件,比如NotifyProgress,并将其绑定到您拥有后台工作者的类。

所以:

 //In class ProgressClass. 
 public event EventHandler<ProgressClassEventArgs> NotifyProgress = (s, e) => {};

接下来:

 private void bw_DoWork(object sender, DoWorkEventArgs e)
 {
     ProgressClass obj = new ProgressClass();

     //Here you hook up the event
     obj.NotifyProgress += this.OnProgressChanged;

     Importer tradeImporter = e.Argument as Importer;
     BackgroundWorker worker = sender as BackgroundWorker;
     List<TradeUploadInfo> list = obj.AllocateTrades2(tradeImporter, false);
     e.Result = list; //Passes the list for processing
 }

事件处理程序如下所示:

private void OnProgressChanged(object sender, ProgressClassEventArgs e) 
{
   worker.ReportProgress(e.Progress);
}

没关系,因为你可以(或者你已经做过)让工人成为这个班的一员。

在这种情况下,您需要定义ProgressClassEventArgsEventArgs子类)并添加类型为int的Progress属性,以匹配ReportProgress args。

答案 2 :(得分:1)

如果您能够/愿意修改obj.AllocateTrades2方法,您可以yield结果,然后在循环中将每个项目添加到列表中。

示例:

public IEnumerable<TradeUploadInfo> AllocateTrades2(Importer tradeImporter, bool foo)
{

    foreach( ... )
    {
        TradeUploadInfo bar; // = ...
        // ...
        yield return bar;
    }

}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    ProgressClass obj = new ProgressClass();
    Importer tradeImporter = e.Argument as Importer;
    BackgroundWorker worker = sender as BackgroundWorker;
    List<TradeUploadInfo> list = new List<TradeUploadInfo>();
    foreach ( TradeUploadInfo info in obj.AllocateTrades2(tradeImporter, false) )
    {
        list.Add( info );
        // ... progress
    }
    e.Result = list; //Passes the list for processing
}

这里的美妙之处在于你可以像以前一样使用AllocateTrades2 (意味着你不必修改现有代码或重载函数)嗯......实际上,你需要修改明确期望List的代码,可能只需在函数调用之后添加.ToList(),并且您不需要添加事件(当它可以获得a little tricky时来垃圾收集)。

相关问题