BackgroundWorker and incremental results

V

vulpes

How do I implement the "incremental results" with a BackgroundWorker?
Many pages,

http://msdn2.microsoft.com/en-us/library/wewwczdw.aspx

for example, tell that I should subclass the ProgressChangedEventArgs
class, but what else? I haven't found any examples. (Why aren't there
any?) Right now I have derived my own version of
ProgressChangedEventArgs with some extra properties, declared

public delegate void FilterWorkerProgressChanged(Object sender,
FilterProgressChangedEventArgs e);
public event FilterWorkerProgressChanged FilterProgressChanged;

in the publisher class and added a handler for this event here:

filterWorker.FilterProgressChanged +=
progDialog.filterWorker_ProgressChanged;

Of course, right now calling ReportProgress doesn't do anything
because it will raise a ProgressChanged event, which is unhandled. How
do I raise that FilterProgressChanged event or do I even need to make
my own event for this? I guess one way would be to subclass
BackgroundWorker, but that CANNOT be the easiest way to do it. And
then I would have to guess what to write to those overridden
ReportProgress, OnProgressChanged, etc., not good.

A simple (but rigorous) example would be the best answer. I just
started learning C# like two days ago (I like it thus far), so its
event handling model (or paradigm.........) is still a bit mystery to
me.

Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

Unfortunately, subclassing the BackgroundWorker class is exactly what
you have to do. There is no way to fire the event you want without using a
subclass (which would require you to override the OnProgressChanged method
to fire your event).

You could always use the overload of ReportProgress which takes a
parameter of type Object, but if your needs dictate that the specialization
is necessary, then subclasisng is the only way to go.
 
G

Gaz

Nicholas Paldino said:
Unfortunately, subclassing the BackgroundWorker class is exactly what
you have to do. There is no way to fire the event you want without using
a subclass (which would require you to override the OnProgressChanged
method to fire your event).

You could always use the overload of ReportProgress which takes a
parameter of type Object, but if your needs dictate that the
specialization is necessary, then subclasisng is the only way to go.

Can't you do it this way?

Call worker.ReportProgress from within DoWork and pass some state object
thus:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
...
worker.ReportProgress(progressPercentage, state); // state
contains incremental results
...
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs
e)
{
// Now we are in the main form thread
// e.UserState will hold our state object, cast it back and use it as
you will
// Or raise your own custom event from here
OnMyCustomEvent(this, new MyCustomEventArgs(...))
}

private void OnMyCustomEvent(object sender, MyCustomEventArgs e)
{
if (MyCustomEvent != null)
MyCustomEvent(sender, e)
}
}

This is the way I am doing it atm.
Gaz
 
V

vulpes

You could always use the overload of ReportProgress which takes a
parameter of type Object, but if your needs dictate that the specialization
is necessary, then subclasisng is the only way to go.

But I understand that using the userState object is exactly what you
must NOT do in this situation. The MSDN Docs always talk about using
the userState strictly as an ID for the worker and you will burn in
hell (deadlocked there...) if you use it for some other thing (for
example change it during the run). On the other hand I've seen many
people in the net talk about using it and then wondering why it
doesn't work. So if you're really gonna tell me that I can do that
then please, say it again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top