Reputation:
I want to run an action asynchronously, and report the time the action took using dots (For each quarter, append a new dot to the text box). Here's what I have so far.
private void ReportAction(string label, Action action)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = false;
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler((object sender, DoWorkEventArgs e) =>
{
action();
});
worker.ProgressChanged += new ProgressChangedEventHandler(this.OnProgressChanged);
this.LogTextBox.AppendText(label);
worker.RunWorkerAsync();
}
private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage % 25 == 0)
{
this.LogTextBox.AppendText(" .");
}
}
As you can see, it initializes a new BackgroundWorker for the action, writes the "label" to the textbox text and then checks if the progress is a quarter and adds a dot if so. The output will eventually be like so:
Initializing SomeMethod . . . .
Each dot will appear after each quarter is done.
However, the problem I'm facing is with ReportProgress method of the BackgroundWorker Class. I'm not sure where to call it, and what to put in it's parameters. Can anyone help me?
Upvotes: 0
Views: 577
Reputation: 152556
I'm not sure where to call it, and what to put in it's parameters.
From MSDN:
If you need the background operation to report on its progress, you can call the ReportProgress method to raise the ProgressChanged event. The WorkerReportsProgress property value must be true, or ReportProgress will throw an InvalidOperationException.
It is up to you to implement a meaningful way of measuring your background operation's progress as a percentage of the total task completed.
From what you've shown that call would go somewhere in action()
.
Typically you put in some sort of "% complete" value - if you're looping through some collection, measure how many items out of the total number have been processed.
As a side note, I would not use e.ProgressPercentage % 25
as a measure, since it's perfectly feasible for the percentage to jump from 26
to 27
.
Upvotes: 0
Reputation: 14618
However, the problem I'm facing is with ReportProgress method of the BackgroundWorker Class. I'm not sure where to call it, and what to put in it's parameters. Can anyone help me?
You would call it in action();
aka the method which does the work.
E.g
public void action()
{
//do some work
worker.ReportProgress(percentValue);
}
ReportProgress()
can take an int
percentage value or a percentage and an object to pass to your OnProgressChanged
event.
Upvotes: 0
Reputation: 156978
You should pass the background worker to the Action
:
private void ReportAction(string label, Action<BackgroundWorker> action)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = false;
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler((object sender, DoWorkEventArgs e) =>
{
action(worker);
});
worker.ProgressChanged += new ProgressChangedEventHandler(this.OnProgressChanged);
this.LogTextBox.AppendText(label);
worker.RunWorkerAsync();
}
private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage % 25 == 0)
{
this.LogTextBox.AppendText(" .");
}
}
In your action, you can report progress back now:
private void actionDelegate(BackgroundWorker bgw)
{
bgw.ReportProgress(50);
}
You can also make this less dependent on the BackgroundWorker
by providing an interface doing this for you.
Upvotes: 1