Help with threading/control.invoke

R

Rich

Sorry for looking for help with what are probably very elementary
issues, but I'm new to both .NET and the CF and getting frustrated.
I've seen several examples on this board and on MSDN which have gotten
me along the correct path (I think) but I'm not quite putting all of
the pieces together.

Basically, a series of processing steps are executed upon click of a
button. As these steps are executed, I would like to update status and
progress bars on the calling form. I think I need to start a thread in
the button click event and use control.invoke in the class method to
update form elements. Please see psuedo code below:

*******************************************************************

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Project
{
public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.StatusBar statusBar1;

public Form2()
{
InitializeComponent();

}
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}

private void InitializeComponent()
{
private void button1_Click(object sender, System.EventArgs e)
{
//kick off series of processing steps
//need to update status and progress bar as processing progresses
Class1 processor = new Class1();
//start thread?
processor.processStuff();
}
}

using System;

namespace EquipCertification
{
public class Class1
{
public Class1()
{
}
public void processStuff()
{
//processing step 1
//update status bar/progress bar
//control.invoke?

//processing step 2
//update status bar/progress bar //control.invoke?

//processing step 3
//update status bar/progress bar
//control.invoke? }
}
}

*******************************************************************
Any suggestions or advice?

Thank you in advance.

Rich
 
M

Maarten Struys, eMVP

It depends on the execution time of your function 'ProcessSfuff'. If it runs
for a long time you want to run it in a separate thread, because otherwise
the UI would seem unresponsive. If that is the case, create a thread as
follows:

private void button1_Click(object sender, System.EventArgs e)
{
Class1 processor = new Class1(this);
Thread processThread = new Thread(new ThreadStart(processor.ProcessStuff));
processThread.Start();
}

The other thing you want to have in your Form2 class is a method to be
called using Control.Invoke. This method should have the same signature as
an event handler. Since you can't pass parameters to Control.Invoke, you
also might consider adding an extra string that you set to the text you want
to show in the StatusBar prior to updating the StatusBar using
Control.Invoke, e.g.

// property to set a new text for the status bar
public string StatusBarText
{
set
{
statusBarText = value;
}
}

// the method to be called by control invoke.
// it actually shows the text previously set using the StatusBarText
property
public void UpdateStatusBar(object sender, EventArgs e)
{
statusBar1.Text = statusBarText;
}

Your class 1 would look something like this:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace SmartDeviceApplication4
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
private Form1 parentForm;

public Class1(Form1 parentForm)
{
this.parentForm = parentForm;
}

public void ProcessStuff()
{
// simulate processing step 1
Thread.Sleep(1000);

// update the UI using Control.Invoke
parentForm.StatusBarText = "Executed step 1";
parentForm.Invoke(new EventHandler(parentForm.UpdateStatusBar));

// simulate processing step 2
Thread.Sleep(1000);

// update the UI using Control.Invoke
parentForm.StatusBarText = "Executed step 2";
parentForm.Invoke(new EventHandler(parentForm.UpdateStatusBar));
}
}
}

Hopefully this helps you a bit further. If you want to know more about
multithreaded application development (and with it about updating UI
controls inside worker threads) you might consider listening to this
WebCast:
http://msevents.microsoft.com/CUI/W...&EventCategory=5&culture=en-US&CountryCode=US

--
Regards,

Maarten Struys, eMVP
PTS Software bv

www.opennetcf.org | www.dotnetfordevices.com
 
D

Daniel Moth

This is a classic scenario for using the BackgroundWorker:
http://www.danielmoth.com/Blog/2004/12/backgroundworker-for-cf-10.html

See the sample for it here:
http://www.danielmoth.com/Blog/2004/12/backgroundworker-sample.html

Basically, in the DoWork event handler do all your background work without
touching the UI, when you feel like updating the UI, call ReportProgress
(takes an int and an object) passing any values you want; at that point your
ProgressChanged event handler runs where you have the two arguments and can
touch the UI.

Cancelling is also supported but it doesn't sound like you need that so you
can ignore the feature.

Cheers
Daniel
 
R

Rich

Excellent! It works exactly like I need. I'm not sure exactly where I
went wrong, but I was close.

Thanks 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