By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,759 Members | 1,244 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,759 IT Pros & Developers. It's quick & easy.

invoke vs begininvoke, mdi/child and showdialog

P: n/a
vs2005, c#
Trying to understand why one way works but the other doesnt.
I have not tried to create a simpler mdi/child/showdialog app for posting
purposes (I think even this would not be so small or simple). I am hoping
the description will generate some ideas I can check out.
PROBLEM:
-----------------
Switching to UI thread using Invoke(), everything seems good.
Switching to UI thread using BeginInvoke(), Invoke() call from another
thread hangs.
APPLICATION INFO:
-------------------------------
MDI application.

MDI creates a 2nd thread (th_mdi). th_mdi has an event it fires when it
receives messages.

Multiple identical child windows. Each subscribes to the th_mdi event.
Each uses either Invoke() or BeginInvoke() to switchover to UI thread when
receiving the event. Each displays data received from the event in a
richtextbox.

One child window creates a new (different) form and shows it modally using
ShowDialog(). The new form periodically updates its diplay, via a
backgroundworker. The new form creates its own 2nd thread (th_form).
th_form sends a bunch of data out, then calls the new form to give status. <
for test purposes, the data going out is externally routed back to th_mdi to
cause it to start firing events >
RESULT: (if the th_mdi event uses Invoke()) The new form uses Invoke() to
swithover to the UI thead to display a status message. th_tx then calls
the new form to give a done msg and exits. The new form uses Invoke() to
swithover to the UI thead to update its display then closes itself.
RESULT: (if the th_mdi event uses BeginInvoke()) The new form tries to
Invoke() to switchover to the UI thread, but it hangs here, forever.
VISUAL INFO:
---------------------
When using Invoke(), each child window is updating its displayed data
syncronous with the other child windows (as expected).

When using BeginInvoke(), it starts with the same behavior, but will
eventually change to going round robin between the child windows, updating
each with a number of messages before switching to the next child window.
(would not expect this to matter)

All of the child windows seem to finish receiving messages, and are no
longer updating their displays.

The other form completes sending its data but never closes. It continues to
update its display.
QUESTIONS:
--------------------
Mdi / Child / modal form from ShowDialog..... Is the ShowDialog() having
some interaction that leads to this?

Using BeginInvoke(), when each of the child windows starts processing many
queued event messages at a time (see visual info section), can one of these
messages somehow get lost, and thereby somehow lock the other thread out?
TIA
Oct 18 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
From what I gather, it seems like you have a simple deadlock operation.
It appears that you have code that is executed when you marshal the call to
the UI thread which the background worker thread is dependent on completing.
The reason Invoke works is that the call to Invoke waits until the call is
completed on the UI thread. With BeginInvoke, the call is marshaled to the
thread, but then your code continues.

It looks like you are going ahead and executing that code when you
should probably be waiting, as there is state that is dependent in the code
after the call to Invoke/BeginInvoke which is not set.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"ke******@nospam.nospam" <ke******************@discussions.microsoft.com>
wrote in message news:2D**********************************@microsof t.com...
vs2005, c#
Trying to understand why one way works but the other doesnt.
I have not tried to create a simpler mdi/child/showdialog app for posting
purposes (I think even this would not be so small or simple). I am hoping
the description will generate some ideas I can check out.
PROBLEM:
-----------------
Switching to UI thread using Invoke(), everything seems good.
Switching to UI thread using BeginInvoke(), Invoke() call from another
thread hangs.
APPLICATION INFO:
-------------------------------
MDI application.

MDI creates a 2nd thread (th_mdi). th_mdi has an event it fires when it
receives messages.

Multiple identical child windows. Each subscribes to the th_mdi event.
Each uses either Invoke() or BeginInvoke() to switchover to UI thread when
receiving the event. Each displays data received from the event in a
richtextbox.

One child window creates a new (different) form and shows it modally using
ShowDialog(). The new form periodically updates its diplay, via a
backgroundworker. The new form creates its own 2nd thread (th_form).
th_form sends a bunch of data out, then calls the new form to give status.
<
for test purposes, the data going out is externally routed back to th_mdi
to
cause it to start firing events >
RESULT: (if the th_mdi event uses Invoke()) The new form uses Invoke()
to
swithover to the UI thead to display a status message. th_tx then calls
the new form to give a done msg and exits. The new form uses Invoke() to
swithover to the UI thead to update its display then closes itself.
RESULT: (if the th_mdi event uses BeginInvoke()) The new form tries to
Invoke() to switchover to the UI thread, but it hangs here, forever.
VISUAL INFO:
---------------------
When using Invoke(), each child window is updating its displayed data
syncronous with the other child windows (as expected).

When using BeginInvoke(), it starts with the same behavior, but will
eventually change to going round robin between the child windows, updating
each with a number of messages before switching to the next child window.
(would not expect this to matter)

All of the child windows seem to finish receiving messages, and are no
longer updating their displays.

The other form completes sending its data but never closes. It continues
to
update its display.
QUESTIONS:
--------------------
Mdi / Child / modal form from ShowDialog..... Is the ShowDialog() having
some interaction that leads to this?

Using BeginInvoke(), when each of the child windows starts processing
many
queued event messages at a time (see visual info section), can one of
these
messages somehow get lost, and thereby somehow lock the other thread out?
TIA

Oct 18 '07 #2

P: n/a
Thanks for the replay.

I mentioned the backgroundworker (which updates the form) for completeness.
I can block starting it up and the problem still occurs.

The Invokes to the UI are updating controls (progress bar, label, rtb) and
exiting. I do not see anything they would be contending for... other than
access to the UI thread.

I was trying to turn off more stuff when I received a null ref exception on
the Invoke() command (pasted further down). Nothing should have been or
appeared to be null. But while looking at this I noticed that the thread was
set as multi apartment vs single apartment. I added the following to the
thread creation sections:
thread_1.ApartmentState = ApartmentState.STA;
So far after switching to STA it is not hanging up.
???
If this is in fact a solution, I am not sure why a MTA thread would be an
issue?
Not sure what was null for the exception. Everything looked ok. ?

exception:
System.NullReferenceException occurred
Message="Object reference not set to an instance of an object."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.WaitForWaitHandle(Wai tHandle
waitHandle)
at System.Windows.Forms.Control.MarshaledInvoke(Contr ol caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
...... <the line calling Invoke()>

"Nicholas Paldino [.NET/C# MVP]" wrote:
From what I gather, it seems like you have a simple deadlock operation.
It appears that you have code that is executed when you marshal the call to
the UI thread which the background worker thread is dependent on completing.
The reason Invoke works is that the call to Invoke waits until the call is
completed on the UI thread. With BeginInvoke, the call is marshaled to the
thread, but then your code continues.

It looks like you are going ahead and executing that code when you
should probably be waiting, as there is state that is dependent in the code
after the call to Invoke/BeginInvoke which is not set.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
Oct 19 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.