Multi-threading and save UI updating

J

John Smith

I'm busy developing a WinForms application that would be responsible for
polling a database and performing some manipulation of the data retrived.
Altough it would be running as a server-side application it requires a GUI
in order to show what is currently processing and some summary information.

When the application starts I start a seperate worker thread using a custom
delegate (in case I need to pass paramates in the future), this worker
thread is responsible for polling the database and in turn starts up between
5 and 15 seperate worker threads of its own. I need to verify two things:

1. I do ensure that I always update the UI from the UI thread. (see UpdateUI
in code below.) What I'm not sure about is whether I need to use lock to
synchronize access and if so where I need to use it. The attached sample
includes comments to explain this better. Do I need to use lock at all?

2. Is it acceptable to start the worker thread from the constructor of
ControlUI?

Below is a code sample to illustate my questions a bit better. ControlUI is
the Form that will be the main interface and Controller is where all work
will happen. Controll will problem start multiple worker threads of its own
in the future.

I hope I explained my question clearly. I had referred to both Windows Form
Programming in C# and Inside C# but I'm still not sure whether this
implemention is acceptable.

public class ControlUI : System.Windows.Forms.Form
{

delegate void MyCustomDelegate();
// UI delegate
delegate void UpdateUIDelegate(string text);

public ControlUI()
{
InitializeComponent();

MyCustomDelegate myCustomDelegate = new MyCustomDelegate
(StartControllerOnWorkerThread);
myCustomDelegate.BeginInvoke(null, null);
}

private void StartControllerOnWorkerThread()
{
new Controller(this).Process();
}

public void UpdateUI(string text)
{
// Make sure we are on the UI thread
if(this.InvokeRequired == false)
{
// SHOULD LOCKING HAPPEN HERE????
// lock (this)
// {
field_Status.Text = text;
// }
}
else
{
// complete work asynchronously
UpdateUIDelegate updateUIDelegate = new UpdateUIDelegate(UpdateUI);
this.BeginInvoke(updateUIDelegate, new object[] { text });
}
}
} // class ControlUI


public class Controller
{
private ControlUI cui = null;

public Controller(ControlUI cui)
{
this.cui = cui;
}

public void Process()
{
/* IS THIS CORRECT? OR SHOULD LOCKING RATHER HAPPEN IN ControlUI???
* Keep in mind that Controller would later itself create multiple worker
threads
* which would call methods in Controller to update UI status.
* PERHAPS Lock is not required at all?
*/
lock (this)
{
cui.UpdateUI("Getting records to process.");
}
}
}
 
J

Jon Skeet [C# MVP]

John Smith said:
I'm busy developing a WinForms application that would be responsible for
polling a database and performing some manipulation of the data retrived.
Altough it would be running as a server-side application it requires a GUI
in order to show what is currently processing and some summary information.

When the application starts I start a seperate worker thread using a custom
delegate (in case I need to pass paramates in the future), this worker
thread is responsible for polling the database and in turn starts up between
5 and 15 seperate worker threads of its own. I need to verify two things:

1. I do ensure that I always update the UI from the UI thread. (see UpdateUI
in code below.) What I'm not sure about is whether I need to use lock to
synchronize access and if so where I need to use it. The attached sample
includes comments to explain this better. Do I need to use lock at all?

If you're passing all the parameters in the delegate, you shouldn't
need to lock at all. If some of your parameters become mutable and you
use BeginInvoke rather than Invoke, you would need to lock at that
stage to make sure you display a consistent state, but hopefully that
won't be a problem.
2. Is it acceptable to start the worker thread from the constructor of
ControlUI?

Absolutely - certainly the threading won't care. Whether it's the best
way of doing it in terms of encapsulation is a different question, but
without knowing more about the app I can't really answer it for sure.
 

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