Threads, InvokeRequired & Form Controls

B

Bill McCormick

Hello,


A timer control (I think) runs in another thread apart from a main form.
In the OnTick event, you can update some form control with no worries.

I'm making an AsyncronousServer class that runs in a separate thread and
I'd like to have server generated events (OnListen, OnConnect, OnSend,
OnRecieve, and so on) update a form control.

The only way I can figure out how to do this is to check InvokeRequired
and use Invoke on the form control from the event handler.

Is this the best way to do this? How does the timer control do this?


Cheers,
Bill
 
S

Serge Baltic

Hello,
A timer control (I think) runs in another thread

System.Windows.Forms.Timer runs on the UI thread and can freely interact
with controls.

The alternative Timer classes in another namespaces run on another threads
and they cannot interact with the UI.
The only way I can figure out how to do this is to check
InvokeRequired and use Invoke on the form control from the event
handler.

Is this the best way to do this?

Yes, it's just OK. Here is some reading on how it's done in .NET Framework
3.0: http://msdn2.microsoft.com/en-us/library/ms741870.aspx.

(H) Serge
 
P

Peter Duniho

Bill McCormick said:
A timer control (I think) runs in another thread apart from a main form.
In the OnTick event, you can update some form control with no worries.

I'm making an AsyncronousServer class that runs in a separate thread and
I'd like to have server generated events (OnListen, OnConnect, OnSend,
OnRecieve, and so on) update a form control.

The only way I can figure out how to do this is to check InvokeRequired
and use Invoke on the form control from the event handler.

Is this the best way to do this? How does the timer control do this?

I haven't used the timer control, but if it truly runs on a different thread
then it does have to do Invoke or BeginInvoke to run code on the main UI
thread. (If the timer control actually just uses WM_TIMER messages, then it
doesn't really run on a different thread per se, as the OS is handling the
timing issues for you, and the issue goes away).

And yes, you need to also use Invoke or BeginInvoke to do the same.
Personally, I remain unconvinced that there's any good reason to use
InvokeRequired. I prefer to have the invoking method different from the
method that actually does the work anyway, and breaking the recursion of
Invoking the same method that does the Invoke is the only real benefit of
using InvokeRequired (and so isn't necessary when two different methods are
used).

For example:

private void _CrossThreadSetText(string strNew)
{
Invoke(new SetTextDelegate(_SetText), new object[] { strNew });
}

private void _SetText(string strNew)
{
label1.Text = strNew;
}

In the above example, all callers could use _CrossThreadSetText, or you
could limit its use to just other threads, letting callers you know are
running on the main thread call _SetText directly. Either will work fine,
and there's no need to call InvokeRequired.

Frankly, I find the convention used everywhere in the MSDN documentation of
having a re-entrant invoking method to be very awkward.

Pete
 
B

Bill McCormick

Serge said:
Hello,



System.Windows.Forms.Timer runs on the UI thread and can freely interact
with controls.

The alternative Timer classes in another namespaces run on another
threads and they cannot interact with the UI.



Yes, it's just OK. Here is some reading on how it's done in .NET
Framework 3.0: http://msdn2.microsoft.com/en-us/library/ms741870.aspx.
Wow! Thanks! This will take some time to get through. Does this have
anything to do with Marshalling? I found something about Marshalling at
http://weblogs.asp.net/justin_rogers/articles/126345.aspx; Marshalling
and Remoting is a topic that I conviently skipped in my Programming C#
book. Maybe I need to look more closely at using Marshalling?

Regards,

Bill
 
S

Serge Baltic

Hello,
Wow! Thanks! This will take some time to get through.

Please note that the above link about .NET 3.0 describes the threading model
of the 3.0-and-above framework, and won't work out of the box on 2.0 and
below. It's possible to implement that model on 2.0 and 1.x frameworks, but
that's worth the effort in relatively large apps only, or if you're going
to reuse it. Writing all that stuff for one-time use in a small utility is
more like a waste of time (or pure self-education, whichever you prefer :).
Does this have
anything to do with Marshalling? I found something about Marshalling
at http://weblogs.asp.net/justin_rogers/articles/126345.aspx;
Marshalling and Remoting is a topic that I conviently skipped in my
Programming C# book. Maybe I need to look more closely at using
Marshalling?

No, not quite. Unlike COM/ActiveX, .NET has almost no marshalling when calling
across the threads, reference and value types are passed transparently. As
for Remoting, I think it's an overkill for the task, also. Creating an invisible
form on the main thread and using Invoke on it will be just enough to fire
a couple events on a single class.

(H) Serge
 

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