Best way to update UI from polling task?

M

Mark Huebner

I need to create a Windows application that polls a device through a serial
port and updates textboxes on a form with the data received from the device.
The polling task also needs to update a SQL Server 2005 database with the
data received from the device. This application also needs to periodically
send some data from the SQL Server database to the this device through the
same serial port. Reading from and writing to the serial port does not have
to occur simultaneously.

I first tried to do this by creating a separate thread that does the polling
but the thread doesn't have access to the components on the Windows form. I
read that it is possible to update the UI using delegates and the Invoke
method but this seemed too complicated and limiting. I was also concerned
about restrictions on what can be done in threads and that I might not be
allowed to update our SQL Server database from a secondary thread.

I then tried to create a polling loop in the form's Shown event, but the
loop freezes the form. Is there a pause-like statement I can add to my
processing loop that allows other form related processing to occur and form
events to fire? What is the best way to perform a background task in a
Windows form application and update the UI (form) from the background task?

The tool I am using is Visual Studio 2005 pro. Thanks in advance!

Mark Huebner
 
M

Mark Huebner

What about using the Application Idle event or a Timer control? Seems like
there are several ways to do this.
 
M

Mark Huebner

I wonder if the Application.Idle event would have direct access to the
forms's controls (textboxes, buttons, etc.) or would I need to use the
Invoke method in it?
 
J

jcreasy

I have done polling loops in seperate threads that use BeginInvoke to
pass information back to the main thread to update a GUI and it's not
too bad. I am not sure about the database portion, but I think it would
be the same. By basic approach is as follows.

Create a custom event and delegate to handle the information that much
be passed from your polling thread to your main thread. For example
let's say you need to pass two ints. Your code to create the event look
as follows.

public class twoIntEventArgs : EventArgs
{
int a, b;

public twoIntEventArgs(int a, int b)
{
this.a = a;
this.b = b;
}
}

public delegate void twoIntEventHandler(object sender, twoIntEventArgs
e);

Now when you throw the event it is caught by your subscriber, but in
the polling thread, so you need to pass it to an identical function in
the main thread. Here are the two function for this.

private void poller_event(object sender, twoIntEventArgs e)
{
object plist = {sender, e};
this.BeginInvoke(new twoIntEventHandler(mainThread_event), plist);
}

private void mainThread_event(object sender, twoIntEventArgs e)
{
//here you can do whatever you need to to your GUI
}

This code is not complete, need some try/catch blocks and such, but
this should give you a start. Please reply if there is anything here
you're having trouble with. Good luck!
 
B

Bruce Wood

I agree. A background thread is the way to go here.

Also, there is no reason why you can't update the database from the
background thread, although I would prefer to do that in a _second_
background thread, so that while you're waiting for the database to
complete an operation neither the UI nor the thread polling the serial
port are impaired.
 
P

Patrice

Also the background component may help as it takes care of calling each
event on the appropriate thread for you masking the invoke mechanism...
 

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