threading and label visibility problem

  • Thread starter Thread starter Mark Denardo
  • Start date Start date
M

Mark Denardo

I stumbled across a weird problem that I don't seem to understand and was
wondering if anyone could help explain why it is occurring:

Basically I have set up a client/server application where the client and
server communicate via a NetworkStream. My problem is on the Client side.

The Client's "Main Thread" starts up a form (Form1) which then invokes a new
thread I'll label as "Listening_Thread". This thread's sole purpose is to
listen to any messages from the Server. So it's sitting on the following
blocking call while waiting from anything from the server:
IncomingMessage = DirectCast(objIFormatter.Deserialize(objNetworkStream),
NetworkMessage)

My program sends a message to the server (on the "Main Thread") requesting
permission to open a new Form on the Client. When the Server responds back
(on the "Listening Thread") with permission granted, that thread opens a new
form (Form2) which when created gets passed an object in the constructor
method that will initilize the form, something like:

Dim obj As New Form2(Initilizing_Object)

The (Form2) constructor will then call an initilizing method with the
Initilizing_Object like so:

Public Sub New(ByVal Initilizing_Object As Object)

InitForm(Initilizing_Object )

Create_Form2_Thread()

End Sub

Then the constructor will create a new thread "Form2_Thread" which calls the
method with the Me.ShowDialog call.

So what I have is the "Main Thread" which handles any GUI actions in (Form1)
and I have the "Listening_Thread" which is a child of the "Main"Thread" and
is blocking while waiting for Server messages, and finally I have a
"Form2_thread" which is a child of the Listening_Thread" which handles any
GUI actions in (Form2). [I'm not sure if that's the best way to set up the
threads I wanted, but since I haven't learned how to communicate between
threads, that is what I used]

Now if I make another request to the Server, it will respond back (on the
"Listening_Thread") to update some label objects on (Form2). What is
happening though, is that when I try to set a label object's Visibililty to
True (Label1.Visible = True), then (Form2) will hang.

What I discovered after much testing, is that when I called the InitForm()
method from the (Form2) constructor, it sets some of the Form's label object
fields to False (Label1.Visibility = False). [This needs to be done, because
the label objects are shown and hidden as part of the application flow]

When I comment out the (Label1.Visibility = False) line in the Initilizing
method, (Form2) no longer hangs. So the setting of the Visibiliy from False
to True is causing the hang in some way.

I next moved the Initilization of (Form2) outside of the constructor like
so:

Dim obj As New Form2()

obj.InitForm(Initilizing_Object)

And this made the whole problem go away - with the (Label1.Visibility =
False) line intact in the Initilizing method.

==> So now I'm total confused. I need to understand what this problem is.
Is it because the threading is set up somehow incorrectly, or because the
Form's constructor is doing something I don't understand, or is it a bug in
the .Net Framework, or perhaps the moon was just lined up incorrectly with
the rest of the planets?

If anybody can understand and explained what is occurring, I'd truly
appreciate it.

-- Mark
 
Mark,

Your current design will not function correctly. This is because you
are attempting to host a form a thread without a message loop. To get
Form2 working correctly it needs to be hosted on the main GUI thread
(which is already running a message loop). You can accomplish this by
using the Invoke method on Form1. The Invoke method will marshal the
execution of any delegate onto the thread hosting the form or control
it was called on. It is also important to know that forms and controls
should only be accessed from the thread hosting them.

Brian
 
Back
Top