3

我的 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 作为参数传递,我将如何bw.ProgressReport在方法内部执行一个不同的类?AllocateTrades2

如果有人向我解释如何处理事件,那就太好了,但如果有另一种优雅的方式。我对想法持开放态度。

4

3 回答 3

5

如果您不想传递整个 BGW(这是有道理的)以免暴露超出它需要知道的内容,一种选择是只传递您分配ReportProgress调用的委托。

调整签名为AllocateTrades2

public List<TradeUploadInfo> AllocateTrades2(
    Importer importer, bool flag, Action<int> reportProgress)

reportProgress在该方法中适当地调用委托。

然后将调用调整为AllocateTrades2

obj.AllocateTrades2(tradeImporter, false,
     progress => worker.ReportProgress(progress));
于 2013-05-21T19:22:26.527 回答
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);
}

没关系,因为您可以(或您已经这样做)让工人成为此类的成员。

在这种情况下,您将需要定义ProgressClassEventArgs(EventArgs子类) 并添加一个Progressint 类型的属性,以匹配ReportProgressargs。

于 2013-05-21T19:22:23.857 回答
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()在函数调用之后添加),并且您不需要添加事件(在垃圾收集方面可能会有些棘手)。

于 2013-05-21T19:40:15.617 回答