473,473 Members | 1,994 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

backgroundwork and progress

am having a hard time wrapping my head around "backgroundworker" class and
updates to the window form that calls it.

i have some questions about how to update windows form controls.
i have multiple labels and i'm using a text box for status updates.
the labels change when a task completes.
the text box report what task is running.

so
1) when i call _ProgressChange i need that function to passed the label i
want updating and what message?
2) does _ProgressChange know how to update the label and text box or do i
have to defind other parameters to link the windows form control to the
_ProgressChange.
3) if i have many functions that start after each other and they give status
do i need a different "backgroundworker" for each function? or can they be
tied to one thread? (each function relays on the first one to finish before
the next one starts).
does anyone or has anyone come across a good complex sample of a
"backgroundwork" class with multiple _ProgressChange?

Jun 27 '08 #1
10 2023
On May 16, 1:26 pm, auldh <au...@discussions.microsoft.comwrote:
am having a hard time wrapping my head around "backgroundworker" class and
updates to the window form that calls it.

i have some questions about how to update windows form controls.
i have multiple labels and i'm using a text box for status updates.
the labels change when a task completes.
the text box report what task is running.

so
1) when i call _ProgressChange i need that function to passed the label i
want updating and what message?
2) does _ProgressChange know how to update the label and text box or do i
have to defind other parameters to link the windows form control to the
_ProgressChange.
3) if i have many functions that start after each other and they give status
do i need a different "backgroundworker" for each function? or can they be
tied to one thread? (each function relays on the first one to finish before
the next one starts).

does anyone or has anyone come across a good complex sample of a
"backgroundwork" class with multiple _ProgressChange?
You don't call your objectName_ProductChanged method. You call the
instance method ReportProgress on the background worker. That method
handles doing the thread switching and raising the _ProgressChanged
event on the proper thread.

So you would have:

private void bworker1_DoWork( object sender, DoWorkEventArgs e ) {
BackgroundWorker worker;

worker = (BackgroundWorker)sender;

for ( int i = 0 ; i < 10 ; i += 1 ) {
worker.ReportProgress( i, null );
}
}

private void bworker1_ProgressChanged( object sender,
ProgressChangedEventArgs e ) {
myProgressBar.Value = e.ProgressPercentage * 10;
}

DoWork occurs on the background thread; all other event handlers for
the BackgroundWorker occur on the UI thread.

HTH
Andy
Jun 27 '08 #2
On Fri, 16 May 2008 10:26:01 -0700, auldh
<au***@discussions.microsoft.comwrote:
am having a hard time wrapping my head around "backgroundworker" class
and
updates to the window form that calls it.
It will be helpful if you first fully comprehend how Invoke() is used
absent a class like BackgroundWorker. Much of what BackgroundWorker does
is encapsulate the call to Invoke() so you don't have to deal with it. If
you don't understand Invoke(), it's hard to understand BackgroundWorker.
i have some questions about how to update windows form controls.
i have multiple labels and i'm using a text box for status updates.
the labels change when a task completes.
the text box report what task is running.

so
1) when i call _ProgressChange i need that function to passed the label i
want updating and what message?
What is "_ProgressChange"? How do you call it? There's no such method in
the BackgroundWorker class, so it's very difficult to know what you're
talking about.

If you really mean BackgroundWorker.ReportProgress(), which raises the
ProgressChanged event, then one overload of ReportProgress() takes an
Object as a parameter. This is copied to the
ProgressChangedEventArgs.UserState property. So you could pass the Label
you want updating, or a more complex class that references the Label and a
message string and anything else you want.
2) does _ProgressChange know how to update the label and text box or do i
have to defind other parameters to link the windows form control to the
_ProgressChange.
Again, what's "_ProgressChange"?

The BackgroundWorker class doesn't know anything about your own UI. All
it knows is to marshal the events ProgressChanged and RunWorkerCompleted
back to the thread on which the BackgroundWorker was created (if
possible...if you create it in a Forms application from the main GUI
thread, which is the usual use of the BackgroundWorker class, then it will
be possible). It is essentially calling Invoke() for you when raising the
ProgressChanged and RunWorkerCompleted events so that you don't have to.

You have to write all of the code to actually update your UI. That code
would go in your ProgressChanged event handler, and so of course you need
to make sure that all of the information that will be needed is passed at
the appropriate time, when you call BackgroundWorker.ReportProgress().
3) if i have many functions that start after each other and they give
status
do i need a different "backgroundworker" for each function? or can they
be
tied to one thread? (each function relays on the first one to finish
before
the next one starts).
Since the BackgroundWorker doesn't know anything at all about how you're
displaying progress, you can do it any way you like. If you want multiple
methods to be called from the same DoWork event of the same
BackgroundWorker, just call those methods from a single method that is
actually the DoWork event handler.
does anyone or has anyone come across a good complex sample of a
"backgroundwork" class with multiple _ProgressChange?
MSDN has sample code using BackgroundWorker. I recommend that you review
and learn that sample code well enough that you can discuss your use of
BackgroundWorker without using the wrong terminology. Once you're using
the correct terms and spelling for everything, it will be a lot easier to
understand your questions.

Pete
Jun 27 '08 #3
thanks Andy.
but what about the questions i have?

"Andy" wrote:
On May 16, 1:26 pm, auldh <au...@discussions.microsoft.comwrote:
am having a hard time wrapping my head around "backgroundworker" class and
updates to the window form that calls it.

i have some questions about how to update windows form controls.
i have multiple labels and i'm using a text box for status updates.
the labels change when a task completes.
the text box report what task is running.

so
1) when i call _ProgressChange i need that function to passed the label i
want updating and what message?
2) does _ProgressChange know how to update the label and text box or do i
have to defind other parameters to link the windows form control to the
_ProgressChange.
3) if i have many functions that start after each other and they give status
do i need a different "backgroundworker" for each function? or can they be
tied to one thread? (each function relays on the first one to finish before
the next one starts).

does anyone or has anyone come across a good complex sample of a
"backgroundwork" class with multiple _ProgressChange?

You don't call your objectName_ProductChanged method. You call the
instance method ReportProgress on the background worker. That method
handles doing the thread switching and raising the _ProgressChanged
event on the proper thread.

So you would have:

private void bworker1_DoWork( object sender, DoWorkEventArgs e ) {
BackgroundWorker worker;

worker = (BackgroundWorker)sender;

for ( int i = 0 ; i < 10 ; i += 1 ) {
worker.ReportProgress( i, null );
}
}

private void bworker1_ProgressChanged( object sender,
ProgressChangedEventArgs e ) {
myProgressBar.Value = e.ProgressPercentage * 10;
}

DoWork occurs on the background thread; all other event handlers for
the BackgroundWorker occur on the UI thread.

HTH
Andy
Jun 27 '08 #4
Auldh,
but what about the questions i have?
Then you should in my idea first give an explanation what your problem is.

Telling that you call _ProgressChange can be very misleading as Andy assumed
that you were invoking the event from the background class, however in fact
there is in my idea not direct a reason to expect thAT, it can be everything
else.

Cor

Jun 27 '08 #5
3) Seems like the operations you want to do in a separate thread are
dependent on one another. Putting heavy work on a separate thread is
ok to make sure your gui remains responsive. Make sure though, that
putting each operation in a separate thread is worth the overhead.
This is a good article:

http://www.yoda.arachsys.com/csharp/threads/

1 + 2 + does anyone or has anyone come across a good complex sample of
a
"backgroundwork" class with multiple _ProgressChange?

You might consider using the Observer pattern

http://en.wikipedia.org/wiki/Observer_pattern

and implement it using thread safe operations:

http://blog.devstone.com/aaron/archi...1/21/1351.aspx

Regards,
Joachim

Jun 27 '08 #6
thanks. i'm sorry if i'm not using the right terms.

i will try to be clearer as i try to explain my issues. i'm suppling a mock
up of my program. i put ":" in place where there is code not related to my
BackgroundWorker.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.VisualBasic;
using System.Threading;
namespace CallFlow
{

public partial class fCallFlow : Form
{

public fCallFlow()
{
InitializeComponent();
InitializeBackgroudWorker();
}
private void InitializeBackgroudWorker()
{
bgWorker.DoWork += new
System.ComponentModel.DoWorkEventHandler(this.bgWo rker_DoWork);
//bgWorker.ProgressChanged += new
ProgressChangedEventHandler(bgWorker_ProgressChang ed);
bgWorker.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(bgWorker_RunWorkerC ompleted);
}
private bool parseuserlog(string filename, string sfilename)
{
:
:
:
//do some work
// update the windows form giving status to the user
tbStatus.Text = "Reading the input file. Creating temp
files.\r\n";
:
//the code for heavy processing
:
:
}//private bool parseuserlog(string filename)

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
runProgram((string)e.Argument, worker, e);
}//private void bgWorker_DoWork(object sender, DoWorkEventArgs e)

private void bgWorker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
MessageBox.Show("Canceled");
this.bgWorker.CancelAsync();
}
else
{
MessageBox.Show("Done");
}
}//private void bgWorker_RunWorkerCompleted(oject sender,
RunWorkerCompletedEventArgs e)
private void bgWorker_ProgressChangeed(object sender,
ProgressChangedEventArgs e)
{
//e.UserState
//ProgressChangedEventArgs.UserState property
}

private void runProgram(string filename, BackgroundWorker worker,
DoWorkEventArgs e)
{
:
//check the windows form to see if a user option is set
if (cbTraces.Checked == true)
bTrace = true;
:
//get the file name to append to the output files.
sfilename = fileChoice.SafeFileName.Substring(0,
fileChoice.SafeFileName.IndexOf("."));
if (worker.CancellationPending)
{
e.Cancel = true;
}
//call the code that does the heavy process
if (!parseuserlog(filename, sfilename))
{
MessageBox.Show("Error in parseuserlog function.");
Application.Exit();
}
:
//provide a status to the window form
tbStatus.Text += "Starting to process the PHHONEMAIL script
data.\r\n";
tbStatus.Refresh();
if (worker.CancellationPending)
{
e.Cancel = true;
}
//code to call another heavy task
if (!parsephonemaildata2(sfilename))
MessageBox.Show("Error");
:
//provide a status to the window form
tbStatus.Text += "Starting to process the Vogue script data.\r\n";
tbStatus.Refresh();

//code to call another heavy task
if (!parsevoguedata2(sfilename))
{
MessageBox.Show("Error in parsevoguedata function.");
Application.Exit();
}
//provide status to the window form
tbStatus.Text += "Starting to process data AVERAGES.\r\n";
tbStatus.Refresh();
if (worker.CancellationPending)
{
e.Cancel = true;
}
//code to call another heavy task
getAverages(sfilename);

}//private void runProgram(string useless, BackgroundWorker worker,
DoWorkEventArgs e)

private void bProcess_Click(object sender, EventArgs e)
{
:
:
//code that starts when the user selects a window form button
:
//start the background thread
bgWorker.RunWorkerAsync(filename);
:
}//private void bProcess_Click(object sender, EventArgs e)

private bool parsephonemaildata2(string sfilename)
{
:
//heavy code task with no status to the window form
:
return (true);
}//private bool parsephonemaildata2()

private bool parsevoguedata2(string sfilename)
{
:
//code for heavy task.
//status to update windows form
tbStatus.Text += "Number of lines ran in VOGUE script: " +
lSessionID.ToString() + "\r\n";
:
return (true);
}//private bool parsevoguedata2()

private void fCallFlow_Load(object sender, EventArgs e)
{
tbVersion.Text = "Version 2.2";
}//private long convertsession(string sSession)

private void bCancel_Click(object sender, EventArgs e)
{
Application.Exit();
}

}//public partial class fCallFlow : Form
}//namespace CallFlow

the windows form "command" button calls "private void bProcess_click(object
sender, EventArgs e)" which when invoked calls the function "private void
runProgram( string useless, BackgroundWorker worker, DoWorkEventArgs e)".
this inturns fires off the worker thread that calls 3 heavy process
functions.

one such function "private bool parseuser(string filename, string
sfilename)" does a heavy number crunching task and has to give an update to
the windows form not to a progress bar but to TextBox which i want to give
verbal updates.

the first issue i have is that i'm not sure if the "worker" object can be
passed down to this function? if so what is the method for this?

i guess if i can do that i can figure it out for the other functions called
by the "runProgram" function that controls the thread. (i'm sorry if still
get the terms wrong).

the sample i found talk about simple process to the progress bar and only 1
level. they don't outline how to update labels, textboxes, and statusbars.

thanks for any help.
Jun 27 '08 #7
On Mon, 19 May 2008 12:46:15 -0700, auldh
<au***@discussions.microsoft.comwrote:
[...]
the first issue i have is that i'm not sure if the "worker" object canbe
passed down to this function? if so what is the method for this?
Of course it can. Just as you pass it to your runProgram() method, your
runProgram() method can pass it to subsequent methods that method calls.

Everywhere that you have code to update status (e.g. >tbStatus.Text +=
"Starting to process the PHHONEMAIL script data.\r\n" <<), you need to
replace that with a call to Invoke() that does the same thing, and get rid
of those calls to Refresh().

Pete
Jun 27 '08 #8
Peter can you expand on your comment:
Everywhere that you have code to update status (e.g. >tbStatus.Text +=
"Starting to process the PHHONEMAIL script data.\r\n" <<), you need to
replace that with a call to Invoke() that does the same thing, and get rid
of those calls to Refresh().
i can not see the forest through the trees. i can not find a good sample of
how to setup the Invoke method within a BackgroundWorker. seems samples use
the "progressbar" as their method of update.

so finding samples on updating labels, textbox and statusbar is difficult.

do i use "Delegate" and "InvokeRequired" in this operation?

"Peter Duniho" wrote:
On Mon, 19 May 2008 12:46:15 -0700, auldh
<au***@discussions.microsoft.comwrote:
[...]
the first issue i have is that i'm not sure if the "worker" object can be
passed down to this function? if so what is the method for this?

Of course it can. Just as you pass it to your runProgram() method, your
runProgram() method can pass it to subsequent methods that method calls.

Everywhere that you have code to update status (e.g. >tbStatus.Text +=
"Starting to process the PHHONEMAIL script data.\r\n" <<), you need to
replace that with a call to Invoke() that does the same thing, and get rid
of those calls to Refresh().

Pete
Jun 27 '08 #9
On Mon, 19 May 2008 16:46:37 -0700, auldh
<au***@discussions.microsoft.comwrote:
Peter can you expand on your comment:
>Everywhere that you have code to update status (e.g. >tbStatus.Text+=
"Starting to process the PHHONEMAIL script data.\r\n" <<), you need to
replace that with a call to Invoke() that does the same thing, and get
rid
of those calls to Refresh().

i can not see the forest through the trees. i can not find a good sample
of
how to setup the Invoke method within a BackgroundWorker. seems samples
use
the "progressbar" as their method of update.
Well, that's sort of the "approved" way to use a BackgroundWorker.
Because the ProgressChanged event is automatically marshaled onto the
correct thread, the Invoke() issue goes away.

And indeed, that would be one way to do it. You could just call
ReportProgress, passing an object that contains the information required
to perform the feedback (for example, a new string to append to a control
and possibly a reference to that control, though in the code you posted
you seem to only ever update one control so that wouldn't necessarily be
needed). Then in your ProgressChanged handler, just update the control
using the string.

For example, where you have some progress to report, it might look like
this:

worker.ReportProgress(0, "Starting to process the PHHONEMAIL script
data.\r\n");

Then in your handler, you'd do this:

void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs
e)
{
tbStatus.Text += e.UserState.ToString();
}

An alternative (and this would be especially appropriate if you're already
using the ProgressChanged event for actual percentage progress updates)
would be to use Invoke() from your BackgroundWorker. In this case, it
would work the same as if you were doing it from any other thread; the
fact that the code is in the DoWork handler of BackgroundWorker is
somewhat irrelevant with this approach.

As an example, the code you have that currently looks like this:

tbStatus.Text += "Starting to process the PHHONEMAIL script data.\r\n";
tbStatus.Refresh();

Would instead look like this:

tbStatus.Invoke((MethodInvoker)delegate
{ tbStatus.Text += "Starting to process the PHHONEMAIL script
data.\r\n"; });

(Note that there's no need to call Refresh() :) )

Hope that helps.

Pete
Jun 27 '08 #10
Peter,
that worked and so easy to implement.

thanks!

"Peter Duniho" wrote:
On Mon, 19 May 2008 16:46:37 -0700, auldh
<au***@discussions.microsoft.comwrote:
Peter can you expand on your comment:
Everywhere that you have code to update status (e.g. >tbStatus.Text +=
"Starting to process the PHHONEMAIL script data.\r\n" <<), you need to
replace that with a call to Invoke() that does the same thing, and get
rid
of those calls to Refresh().
i can not see the forest through the trees. i can not find a good sample
of
how to setup the Invoke method within a BackgroundWorker. seems samples
use
the "progressbar" as their method of update.

Well, that's sort of the "approved" way to use a BackgroundWorker.
Because the ProgressChanged event is automatically marshaled onto the
correct thread, the Invoke() issue goes away.

And indeed, that would be one way to do it. You could just call
ReportProgress, passing an object that contains the information required
to perform the feedback (for example, a new string to append to a control
and possibly a reference to that control, though in the code you posted
you seem to only ever update one control so that wouldn't necessarily be
needed). Then in your ProgressChanged handler, just update the control
using the string.

For example, where you have some progress to report, it might look like
this:

worker.ReportProgress(0, "Starting to process the PHHONEMAIL script
data.\r\n");

Then in your handler, you'd do this:

void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs
e)
{
tbStatus.Text += e.UserState.ToString();
}

An alternative (and this would be especially appropriate if you're already
using the ProgressChanged event for actual percentage progress updates)
would be to use Invoke() from your BackgroundWorker. In this case, it
would work the same as if you were doing it from any other thread; the
fact that the code is in the DoWork handler of BackgroundWorker is
somewhat irrelevant with this approach.

As an example, the code you have that currently looks like this:

tbStatus.Text += "Starting to process the PHHONEMAIL script data.\r\n";
tbStatus.Refresh();

Would instead look like this:

tbStatus.Invoke((MethodInvoker)delegate
{ tbStatus.Text += "Starting to process the PHHONEMAIL script
data.\r\n"; });

(Note that there's no need to call Refresh() :) )

Hope that helps.

Pete
Jun 27 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: SpamProof | last post by:
I got an animated gif that is a barber pole spinning that I want to use as a progress bar. The problem is that is stops spinning (shows 1 frame) when my browser is processing a submited request...
7
by: Pepi Tonas | last post by:
I have a form that takes some time to load because it has to populate some Data. I was trying to display a form on top of it with an activity bar so that user can see that something's going on. ...
1
by: scorpion53061 | last post by:
this code came from cor and I think Armin authored it. I am trying to download an access database and track its progress. It is reading the size fo the file but I am unsure of how to get the...
8
by: Brian Henry | last post by:
I created a smooth progress bar with this code.. but if you update the values in a row quickly of it and watch it on screen it flickers... how would i change this to reduce the flickering?...
8
by: WhiteWizard | last post by:
I guess it's my turn to ASK a question ;) Briefly my problem: I am developing a Windows app that has several User Controls. On one of these controls, I am copying/processing some rather large...
1
by: daniel_xi | last post by:
Hi all, I am running a VS 2003 .NET project on my client machine (Win 2000 SP4, ..NET framework 1.1), running an ASP.NET application on a remote web server (Win 2000 Server, IIS 6.0, .NET...
15
by: eladla | last post by:
Hi! I am creating a composite control the does some of it`s own data access. I want to display a progress bar between the time the page is loaded and the control place holder is displayed and...
5
by: Aggelos | last post by:
Hello I am doing sevreral scripts like sending a newsletter that might take a while to finish first to prevent the browser from timing out and to keep the user informed of the process progress I...
0
by: jags_32 | last post by:
Hello We use MFG-PRO as our ERP system which in turn uses Progress databases. In the old version of SQL 2000, using DTS packages, we used to set the code page via command prompts and execute DTS...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.