Background Worker Updating from a different class (preferably via events)

烂漫一生 提交于 2019-12-14 03:53:27

问题


I have a background worker in my GUI class.

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
}

Importer is my own class. Now, the AllocateTrades2 method has all the processing done in it.

My question is, how would I go about performing a bw.ProgressReport inside the AllocateTrades2 method, which is in a different class without passing the bw as a parameter?

Would be great if someone explained it to me how to do it with events, but if there is another elegant way. I'm open for ideas.


回答1:


If you don't want to pass in the entire BGW (justifiably so) so as to not expose more than it needs to know, one option is to just pass in a delegate that you assign a ReportProgress call to.

Adjust the signature of AllocateTrades2 to be:

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

Invoke the reportProgress delegate as appropriate from within that method.

Then adjust the call to AllocateTrades2 like so:

obj.AllocateTrades2(tradeImporter, false,
     progress => worker.ReportProgress(progress));



回答2:


Well, given the fact that AllocateTrades2 runs in the context of the background worker, any events that it raises are also executed in that context.

So, all you need to do is add a new event in your ProgressClass, say NotifyProgress, and bind it to the class where you have the background worker.

So:

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

And next:

 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
 }

The event handler would look like this:

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

It's OK, since you can (or you already do) have the worker as a member in this class.

You will need to define the ProgressClassEventArgs (EventArgs subclass) and add a Progress property of type int in this case, to match the ReportProgress args.




回答3:


If you are able/willing to modify the obj.AllocateTrades2 method, you can yield results and then add each item to your list in a loop.

Example:

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
}

The beauty here is that you can use AllocateTrades2 exactly as you did before (meaning you don't have to modify existing code or overload the function) (hmm.. actually, you would need to modify code that was explicitly expecting a List, probably by just adding .ToList() after the function call) and you don't need to add events (which can get a little tricky when it comes to garbage collection).



来源:https://stackoverflow.com/questions/16677774/background-worker-updating-from-a-different-class-preferably-via-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!