Some high level C# design advice needed (?multi threading).

B

bob

I am unsure how to approach a C# windows App.

Essentially I want to do this.

I want to write an app that reads from database_A performs some calculations
updates the pretty dials on the screen then writes the 'cooked' data to
database_B (probably not in that order).
Also I will have some buttons on this main window that open some other
winforms so I can capture other bits of info and adjust the main window's
pretty dials and textboxes accordingly.

Being new to C# ( and very rusty at windows apps ) I found the wonderful
drag-and-drop timer double clicked it and low and behold a timer1_Tick event
appeared, wonderful thought I, I'll just put my database reads and screen
update calls in here.

But alas as was kindly pointed out to me every thing is running on a single
thread and while the app patiently waits for these DB calls and whatever
else I've piled into this event (timer1_Tick ) the main window (buttons,
dials etc) sit there completely unresponsive. I've never tried to make this
sort of 'polling' app before the closest I came was making my child windows
non-modal so they didn't freeze up the parent.

So how would more experienced C# programmer approach this at a high level.
the horrid words 'multi-threading' leap to my mind ...

Would it be wise to continue to run the timer on UI thread but each
timer_tick event start a separate thread to read/write the database and
perhaps when that thread has completed create a new thread to update my
screen. Ah bah humbug I really have no clue.

A starting point would be much appreciated ... Google and the beginners
guide to threading will help me with the rest. :)

regards Bob.
 
J

Jon Skeet [C# MVP]

bob wrote:

Would it be wise to continue to run the timer on UI thread but each
timer_tick event start a separate thread to read/write the database and

It's not clear to me why you need a timer. I didn't notice anything
periodic in your description. Could you expand on that a bit?
perhaps when that thread has completed create a new thread to update my
screen. Ah bah humbug I really have no clue.

You don't need to create a new thread to update the screen - you need
to marshall the call back to the UI thread using
Control.Invoke/BeginInvoke.
A starting point would be much appreciated ... Google and the beginners
guide to threading will help me with the rest. :)

Have a look at http://www.pobox.com/~skeet/csharp/threads
and in particular
http://www.pobox.com/~skeet/csharp/threads/winforms.shtml

Jon
 
B

bob

Jon Skeet said:
It's not clear to me why you need a timer. I didn't notice anything
periodic in your description. Could you expand on that a bit?

I think I need the timer because I have to read database_A every few seconds
.... in reality datbase_A is a place holder for an external Device that
intermittedly has results that need to be first retrieved then analysed and
then finally stored into a Database on the PC.

Polling at regular intervals at this point is the only way to get the info
from the device.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Being new to C# ( and very rusty at windows apps ) I found the wonderful
drag-and-drop timer double clicked it and low and behold a timer1_Tick
event appeared, wonderful thought I, I'll just put my database reads and
screen update calls in here.

Almost there, a better way is that the event handler create a thread wich is
the one that do the reads/calculations , after its finish you send an event
for updating the UI , kind of:

void timer1_tick( ... )
{
new Thread( new ThreadStart( workermethod)).Start();
}
void workermethod()
{
//do the stuff
a_control_in_the_UI.Invoke( new MethodInvoker( runAtUI_Thread) );
}

void runAtUI_Thread()
{
//this will execute in the UI thread
//update controls.
}
Would it be wise to continue to run the timer on UI thread but each
timer_tick event start a separate thread to read/write the database and
perhaps when that thread has completed create a new thread to update my
screen. Ah bah humbug I really have no clue.

Yep, use the code above as a guide, I wrote it right here in OE so it would
not compile most probably.
 
J

Jon Skeet [C# MVP]

bob said:
I think I need the timer because I have to read database_A every few seconds
... in reality datbase_A is a place holder for an external Device that
intermittedly has results that need to be first retrieved then analysed and
then finally stored into a Database on the PC.

Polling at regular intervals at this point is the only way to get the info
from the device.

Right, that's fine - it's the polling bit which wasn't clear.

However, you don't need to use a System.Windows.Forms timer. See
http://www.pobox.com/~skeet/csharp/threads/timers.shtml for the various
different options available to you.
 
B

Bjarne Riis

Hello Bob

Strictly speaking you should be using a thread to do the work and then
update your GUI using InvokeRequired / Invoke. But there is a quick and
dirty way to achive the same thing if the workload is not to heavy

private void timer1_tick(...)
{
DoSomeWork();
Application.DoEvents();
DoSomeMoreWork();
Application.DoEvents();
....
UpdateGui();
Application.DoEvents();
}

Again ... this is a very quick and dirty way, so please don´t tell
anyone that you got from me :)

Regards
Bjarne
 
B

Bjarne Riis

Hello Bob

Strictly speaking you should be using a thread to do the work and then
update your GUI using InvokeRequired / Invoke. But there is a quick and
dirty way to achive the same thing if the workload is not to heavy

private void timer1_tick(...)
{
DoSomeWork();
Application.DoEvents();
DoSomeMoreWork();
Application.DoEvents();
....
....
Application.DoEvents();
}

Again ... this is a very quick and dirty way, so please don´t tell
anyone that you got from me :)

Regards
Bjarne
 
B

Bjarne Riis

Hello Bob

Strictly speaking you should be using a thread to do the work and then
update your GUI using InvokeRequired / Invoke. But there is a quick and
dirty way to achive the same thing if the workload is not to heavy

private void timer1_tick(...)
{
DoSomeWork();
Application.DoEvents();
DoSomeMoreWork();
Application.DoEvents();
....
UpdateGui();
Application.DoEvents();
}

Again ... this is a very quick and dirty way, so please don´t tell
anyone that you got from me :)

Regards
Bjarne
 
B

bob

Thanks gents.

I think I have an idea of where I'm going and now its just getting into the
books for a bit to understand what I want to do.

So if I don't process too much in the on_tick1 event I can look at
marshalling the call back to the UI thread using
Control.Invoke/BeginInvoke or maybe the amount of processing isn't important
because this marshalling is keeping the UI responsive, further reading will
enlighten.

And/or I can start a new thread for the time intensive operations in the
on_tick1 event then when it returns update my gauges etc.

And the Application.DoEvents() is a quick and dirty way that will lead me
down the path to purdition from whence I shall be shunned by my betters. ;-)

Time to read play and swear for a while until it all becomes clear

regards Bob.
 

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