Back to Threads

M

Michael C

Hi all,

I'm now trying to update a status indicator via a Timer control on a worker
thread. The status indicator is just a label on the main form, but I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents based on the
Timer control's ticks. Are there any good examples out there and can you
point me to one or two?

Thanks,
Michael C.
 
M

Michael C

It seems that the issue is that issuing SqlCommands on a SqlClient seems to
take over the current thread completely. I thought I could do this all on
the UI thread with a simple Timer control, but that ain't happenin'. Any
ideas on how I can get my Timer control to Tick during SqlCommand
executions? That would be a much simpler and preferable solution than a
separate thread. But I'm open to a separate worker thread if necessary.

Thanks in advance,
Michael C.
 
M

Michael C

Thanks for the link. He has the same example code in his book (Windows
Forms Programming in C#). Problem is that it doesn't solve my real problem,
which is that the SQL Query I'm executing seems to block the Timer() control
Tick event from ever executing. Even when I run the status update code on a
separate thread like in his book... How can I make my Timer() Tick like
it's supposed to?

Thanks,
Michael C.

Miha Markic said:
Hi Michael,

See this fine article (there are 3 parts)
Safe, Simple Multithreading in Windows Forms
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Michael C said:
Hi all,

I'm now trying to update a status indicator via a Timer control on a worker
thread. The status indicator is just a label on the main form, but I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents based on the
Timer control's ticks. Are there any good examples out there and can you
point me to one or two?

Thanks,
Michael C.
 
M

Michael C

....P.S. I've even tried running my SQL Queries using asynchronous delegates
and setting the status updates code on it's own thread... I'm pretty much
lost as to what else I can possibly do to make this work...

Thanks,
Michael C.


Miha Markic said:
Hi Michael,

See this fine article (there are 3 parts)
Safe, Simple Multithreading in Windows Forms
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Michael C said:
Hi all,

I'm now trying to update a status indicator via a Timer control on a worker
thread. The status indicator is just a label on the main form, but I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents based on the
Timer control's ticks. Are there any good examples out there and can you
point me to one or two?

Thanks,
Michael C.
 
J

John Wood

Any timers added in the UI (through the Timer control) require that the
message queue is being pumped in the UI thread for the timer to execute. If
you have executed a synchronous procedure on the UI thread, then the UI
thread will be blocked until the function returns and the timer will not
execute.

You might find that it's better to execute the sqlcommand on a worker thread
(the easiest way is through the thread pool), leaving you free to update the
UI while the sqlcommand is being executed.

--
John Wood
EMail: first name, dot, second name at priorganize.com


Michael C said:
Thanks for the link. He has the same example code in his book (Windows
Forms Programming in C#). Problem is that it doesn't solve my real problem,
which is that the SQL Query I'm executing seems to block the Timer() control
Tick event from ever executing. Even when I run the status update code on a
separate thread like in his book... How can I make my Timer() Tick like
it's supposed to?

Thanks,
Michael C.

Miha Markic said:
Hi Michael,

See this fine article (there are 3 parts)
Safe, Simple Multithreading in Windows Forms
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Michael C said:
Hi all,

I'm now trying to update a status indicator via a Timer control on a worker
thread. The status indicator is just a label on the main form, but I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents based
on
the
Timer control's ticks. Are there any good examples out there and can you
point me to one or two?

Thanks,
Michael C.
 
M

Michael C

Yeah I have a 'not-so-elegant' solution I'm playing with now. I had to use
a Timer from the System.Timers namespace as opposed to the Windows.Forms
timer and then execute the SQL Queries in asynchronous delegates using
callbacks. You'd think there'd be an easier way. I'm sure there's a better
way. It's amazing that something so simple could be so complicated to
implement.

Thanks,
Michael C.

John Wood said:
Any timers added in the UI (through the Timer control) require that the
message queue is being pumped in the UI thread for the timer to execute. If
you have executed a synchronous procedure on the UI thread, then the UI
thread will be blocked until the function returns and the timer will not
execute.

You might find that it's better to execute the sqlcommand on a worker thread
(the easiest way is through the thread pool), leaving you free to update the
UI while the sqlcommand is being executed.

--
John Wood
EMail: first name, dot, second name at priorganize.com


Michael C said:
Thanks for the link. He has the same example code in his book (Windows
Forms Programming in C#). Problem is that it doesn't solve my real problem,
which is that the SQL Query I'm executing seems to block the Timer() control
Tick event from ever executing. Even when I run the status update code
on
a
separate thread like in his book... How can I make my Timer() Tick like
it's supposed to?

Thanks,
Michael C.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Hi all,

I'm now trying to update a status indicator via a Timer control on a
worker
thread. The status indicator is just a label on the main form, but I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents
based
on can
you
 
J

John Wood

Yeah you would think it would be easier I know. ADO.Net isn't exactly the
holy grail it's often made out to be.

Keep in mind that so-called 'asynchronous delegates' may be asynchronous,
but they simply execute on a temporary worker thread taken from the thread
pool. There 2 problems with this. Firstly, the thread pool has a limit of 64
threads, if more than that are in use, the operation will be queued until a
thread slot is availble. Secondly, it's unnecessary -- these sql operations
are asynchronous in nature (ie. they send data over sockets, and then wait
for the response from the server). It's unnecessary to have a thread
dedicated to waiting for the data to come back when it could just have the
socket send a message to the UI when the data is available. All of the async
mechanisms in .net use the thread-pool, even web-requests. All seems a bit
silly if you ask me.

--
John Wood
EMail: first name, dot, second name at priorganize.com


Michael C said:
Yeah I have a 'not-so-elegant' solution I'm playing with now. I had to use
a Timer from the System.Timers namespace as opposed to the Windows.Forms
timer and then execute the SQL Queries in asynchronous delegates using
callbacks. You'd think there'd be an easier way. I'm sure there's a better
way. It's amazing that something so simple could be so complicated to
implement.

Thanks,
Michael C.

John Wood said:
Any timers added in the UI (through the Timer control) require that the
message queue is being pumped in the UI thread for the timer to execute. If
you have executed a synchronous procedure on the UI thread, then the UI
thread will be blocked until the function returns and the timer will not
execute.

You might find that it's better to execute the sqlcommand on a worker thread
(the easiest way is through the thread pool), leaving you free to update the
UI while the sqlcommand is being executed.
code
on
a
separate thread like in his book... How can I make my Timer() Tick like
it's supposed to?

Thanks,
Michael C.

"Miha Markic [MVP C#]" <miha at rthand com> wrote in message
Hi Michael,

See this fine article (there are 3 parts)
Safe, Simple Multithreading in Windows Forms
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Hi all,

I'm now trying to update a status indicator via a Timer control on a
worker
thread. The status indicator is just a label on the main form,
but
I'm
having trouble figuring out exactly how to implement a separate worker
thread or asynchronous delegate that changes the label contents
based
on
the
Timer control's ticks. Are there any good examples out there and can
you
point me to one or two?

Thanks,
Michael C.
 
M

Michael C

I am a little disappointed that there's no built-in simple (50 words or
less) way to update the UI from a worker thread. I would think this would
be a very common problem that programmers run up against all the time. As
for the SQL operations running asynchronously, for whatever reason (maybe
because I'm running them on a local SQL Server??) the SqlCommands I'm
sending are completely blocking the Windows Forms.Timer() control. I've
verified that it doesn't Tick at all until the SqlCommand has finished
executing. I thought the SqlCommands ran asynchronously also, but it
doesn't look like it; or maybe there's an asynchronous option on the
SqlCommand I'm missing? As far as the limits on the thread pool, that
shouldn't be a problem. The only two things I'm doing at any one time are:
1) running one SqlCommand at a time and 2) updating the status on the UI.
Other than that, all other processing occurs in the UI thread.

Thanks for the help!

Michael C.
 
N

Norvin Laudon

Michael C said:
Thanks for the link. He has the same example code in his book (Windows
Forms Programming in C#). Problem is that it doesn't solve my real problem,
which is that the SQL Query I'm executing seems to block the Timer() control
Tick event from ever executing. Even when I run the status update code on a
separate thread like in his book... How can I make my Timer() Tick like
it's supposed to?
If your seperate thread is not responding to Timer events (or any other),
run the thread continuously in a loop and use Thread.Sleep() so as to not
consume the processor.

Norvin
 
J

Jon Skeet [C# MVP]

Michael C said:
I am a little disappointed that there's no built-in simple (50 words or
less) way to update the UI from a worker thread.

I think it's *pretty* simple to write a delegate and then call
Control.Invoke with it, to be honest. You can even do that within a
normal property on the form if you want to make life easier elsewhere.
I would think this would
be a very common problem that programmers run up against all the time. As
for the SQL operations running asynchronously, for whatever reason (maybe
because I'm running them on a local SQL Server??) the SqlCommands I'm
sending are completely blocking the Windows Forms.Timer() control. I've
verified that it doesn't Tick at all until the SqlCommand has finished
executing. I thought the SqlCommands ran asynchronously also, but it
doesn't look like it

No, they don't. Do you know what made you think they do?

As well as the other links mentioned, you might want to read my multi-
threading article:

http://www.pobox.com/~skeet/csharp/multithreading.html
 
M

Michael C

I think it's *pretty* simple to write a delegate and then call
Control.Invoke with it, to be honest. You can even do that within a
normal property on the form if you want to make life easier elsewhere.

Which is all well and good, except in a situation where you need to update
the UI multiple times from the UI thread, and you end up having to use an
Asynchronous callback. The Asynchronous callback means that you're
splitting up one function into two separate functions, for starters. Insert
a line of code for a delegate for the first function. Oops, now we need to
insert a few more lines call the delegate. But wait, what if we need to
alert the user at the end of the operation, such as via a messagebox or
textbox? Well, now we have to break out a simple 4-line if statement with a
couple of Textbox1.Text = "{status}";-type commands and replace at least one
of them with a separate Control.Invoke called via an if
(Textbox1.InvokeRequired) statement.

Like I said in my definition of *simple* - 50 words or less would do nicely.
No, they don't. Do you know what made you think they do?

Other than being told that by others, and not having had any real
performance issues with SQL commands previously, nothing of note. I suppose
I assumed that it would make sense (since SQL Server is a "Server" product),
that VS.NET would issue a SQL Command to the Server and continue processing
until it received a response, as opposed to locking down the whole system
while it waits for SQL Server to respond.
As well as the other links mentioned, you might want to read my multi-
threading article:

I'll take a look at it. Thanks!
 
J

Jon Skeet [C# MVP]

Michael C said:
Which is all well and good, except in a situation where you need to update
the UI multiple times from the UI thread, and you end up having to use an
Asynchronous callback.

Eh? Do you mean you want to update the UI multiple times from a
*different* thread? (Updating the UI multiple times from the UI thread
doesn't require anything like this.)
The Asynchronous callback means that you're
splitting up one function into two separate functions, for starters.

It needn't - you can write properties which hide the change of thread
entirely from calling code. I did this recently in a PocketPC
installation program recently, so that I can do:

Progress = "Doing something else now";

and it'll automatically make the change in the UI thread. No problem,
and pretty easy to write.
Insert
a line of code for a delegate for the first function. Oops, now we need to
insert a few more lines call the delegate. But wait, what if we need to
alert the user at the end of the operation, such as via a messagebox or
textbox? Well, now we have to break out a simple 4-line if statement with a
couple of Textbox1.Text = "{status}";-type commands and replace at least one
of them with a separate Control.Invoke called via an if
(Textbox1.InvokeRequired) statement.

Like I said in my definition of *simple* - 50 words or less would do nicely.

// General purpose single-string-parameter delegate
delegate void SingleStringParameterDelegate(string parameter);

// Should only be executed within the UI thread
void UpdateName (string name)
{
nameTextBox.Text = name;
}

// Executed from a different thread
void OtherProcessing
{
Invoke(new SingleStringParameterDelegate(UpdateName),
new object[]{newName});
}

Without the comments, but with FooBar counting as two words, that's 33
words by my count. More if you include symbols, of course.
Other than being told that by others, and not having had any real
performance issues with SQL commands previously, nothing of note. I suppose
I assumed that it would make sense (since SQL Server is a "Server" product),
that VS.NET would issue a SQL Command to the Server and continue processing
until it received a response, as opposed to locking down the whole system
while it waits for SQL Server to respond.

It doesn't "lock down the whole system" - it makes *that thread* wait
until a response has been received. Good job too, as otherwise you
could end up trying to commit transactions which hadn't even been sent
yet, etc.
 
M

Michael C

It needn't - you can write properties which hide the change of thread
entirely from calling code. I did this recently in a PocketPC
installation program recently, so that I can do:

Progress = "Doing something else now";

I like your example of using properties to hide the change of thread. Where
can I find out more information on that? (Keep in mind I haven't had a
chance to go to your previous link, but I'm about to go there now.)
Specifically I have to change the image on a label and the text of a status
bar. Here's the general flow of my app right now:

1. UI thread: Start Timer() control, with a 200 ms Tick
2. UI thread: Update Statusbar.Text with status message
3. UI thread: Call asynchronous delegate to execute the SQL Query
4. Worker thread: Executing SQL Query
5. UI thread: Update Image on a Label control on the UI every time the
Timer() Ticks
6. Worker thread: Callback from asynchronous delegate
7. Worker thread: Stop Timer()
8. Worker thread: Update Statusbar.Text with status message
9. Worker thread: Initiate MessageBox with message
10. Return control to UI thread

// General purpose single-string-parameter delegate
delegate void SingleStringParameterDelegate(string parameter);

// Should only be executed within the UI thread
void UpdateName (string name)
{
nameTextBox.Text = name;
}

// Executed from a different thread
void OtherProcessing
{
Invoke(new SingleStringParameterDelegate(UpdateName),
new object[]{newName});
}

Without the comments, but with FooBar counting as two words, that's 33
words by my count. More if you include symbols, of course.

That I can use! Thanks! But I still have the issue that I have to do it at
least 3 times... once for the Statusbar, once for the label and once for
the MessageBox, correct?
It doesn't "lock down the whole system" - it makes *that thread* wait
until a response has been received. Good job too, as otherwise you
could end up trying to commit transactions which hadn't even been sent
yet, etc.

That's a great *default* mode, but you don't necessarily want the thread to
wait... like in this instance. Making the UI thread wait effectively locks
down the application, if not the whole system. Wish they had a simple
property assignment to execute SQL statements asynchronously.
 
J

Jon Skeet [C# MVP]

Michael C said:
I like your example of using properties to hide the change of thread. Where
can I find out more information on that? (Keep in mind I haven't had a
chance to go to your previous link, but I'm about to go there now.)

You just need to put the code to call Invoke into the property setter.
For instance:

delegate void StringParameterDelegate (string value);

string Progress
{
set
{
SetProgressInternal(value);
}
}

void SetProgressInternal(string value)
{
if (InvokeRequired)
{
BeginInvoke (new StringParameterDelegate(SetProgressInternal),
new object[]{value});
return;
}
progressLabel.Text = value;
}

All slightly messy because you can't easily set up a delegate to a
property setter, but the calling code doesn't need to know anything
about that.
Specifically I have to change the image on a label and the text of a status
bar. Here's the general flow of my app right now:

1. UI thread: Start Timer() control, with a 200 ms Tick
2. UI thread: Update Statusbar.Text with status message
3. UI thread: Call asynchronous delegate to execute the SQL Query
4. Worker thread: Executing SQL Query
5. UI thread: Update Image on a Label control on the UI every time the
Timer() Ticks
6. Worker thread: Callback from asynchronous delegate
7. Worker thread: Stop Timer()
8. Worker thread: Update Statusbar.Text with status message
9. Worker thread: Initiate MessageBox with message
10. Return control to UI thread

Not entirely sure what you mean by 10 here - the UI thread should
*always* be available for paint requests etc.

Other than that, only 8 looks like it really needs to update the UI
from the worker thread.
// General purpose single-string-parameter delegate
delegate void SingleStringParameterDelegate(string parameter);

// Should only be executed within the UI thread
void UpdateName (string name)
{
nameTextBox.Text = name;
}

// Executed from a different thread
void OtherProcessing
{
Invoke(new SingleStringParameterDelegate(UpdateName),
new object[]{newName});
}

Without the comments, but with FooBar counting as two words, that's 33
words by my count. More if you include symbols, of course.

That I can use! Thanks! But I still have the issue that I have to do it at
least 3 times... once for the Statusbar, once for the label and once for
the MessageBox, correct?

Well, MessageBox can be done in the worker thread, if you want - it
depends what you want the rest of the UI to do, etc. However, if the
status bar and the label change at the same time, it would make sense
to have one delegate to change both.
That's a great *default* mode, but you don't necessarily want the thread to
wait... like in this instance. Making the UI thread wait effectively locks
down the application, if not the whole system. Wish they had a simple
property assignment to execute SQL statements asynchronously.

To be honest, I don't think it would be useful to that many people
compared with the other asynchronous operations - especially bearing in
mind that it's pretty easy to execute it asynchronously using a
delegate anyway.
 

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