Can a Form's parent be in another thread?

  • Thread starter Thread starter Elp
  • Start date Start date
E

Elp

Hi,

Does anybody know if the Parent of a form can safely be set to a form runing
in another thread? I know that it is not possible to call a control's method
from another thread but i didn't anything about my particluar problem.

Thanks.
 
* "Elp said:
Does anybody know if the Parent of a form can safely be set to a form runing
in another thread? I know that it is not possible to call a control's method
from another thread but i didn't anything about my particluar problem.

/Why/ do you need that?
 
Herfried K. Wagner said:
/Why/ do you need that?

I expected this question :-) Well, i have a form (my main form) with some
buttons on it (that's a very simplified description). When the user clicks
on one of the buttons, i'm calling a web service method and that can take
some time. So while the call is being made, i'm displaying a "Please wait"
form with a progress bar on it. I want the user to be unable to use the main
form while the web service call is being made.

To display this waiting form, i've first tried to create a new thread, make
my web service call in this new thread and display the waiting form in the
main UI thread. This didn't work well because for some reason my waiting
form was almost frozen although the web service call was being made in a
separate thread.

So i've took another approach: i am creating a new thread and displaying the
waiting form in this new thread (with the ShowDialog method) then i'm
calling my web service method from the main UI thread. This works grand.
However, i would like to set the Parent property of my waiting form to be my
main form so that the user can not click on the main form while the web
service call is being made.

Have i been clear enough?

Thanks.
 
Try sometihng like this (just types here, not tested):

Private WebServiceProgress As ProgressDialog

Private Sub Button_Click()

WebServiceProgress = New ProgressDialog
WebServiceProgress.MaximumProgress = 100
Dim WebServiceThread As New Thread(AddressOf WebServiceBackground)
WebServiceThread.Start()
WebServiceProgress.ShowDialog
WebServiceProgress.Dispose()
WebServiceProgress = Nothing

End Sub

Private Sub WebServiceBackground()

Do While WebServiceProgress Is Nothing OrElse Not WebServiceProgress.Visible
Application.DoEvents
Loop

' Do work here and update progress...
WebServiceProgress.IncrementProgress()

' When done close progress dialog.
WebServiceProgress.Close()

End Sub

HTH,

Gerrit
 
Hi Elp,

No, this is not possible.
This is restriction of Windows OS.
Normaly windows procedures are not reentrant. To facilitate writing programs
and to ensure backward compatibility with 16 bit versions of the os, windows
designers desided that the winproc has to be executed by only one thread and
this is the thread created the window.
As long as there are no problems with posted messages, sent messages can be
problematic when crossing thread boundaries. In order to solve that problem
sent messages go thru thread message queue when crossing thread boundaries.

So, here what happens if there was possibility wndows created from a thread
to host controls created from different thread:
You know that parent and child controls communicate by sending messages each
other. Children send notfications to their parents when something happen.
Imagine that the parent send a message to one of its children and this
message changes the state of the child. The parent is blocked in SendMessage
call. The child sends a notification to the parent. Becuse they are created
by different threads the message goes thru the parent message queue. Because
the parent is blocked it's message loop is not running so the message won't
be delivered. The child waits as well and... dead lock. That's why windows
designers decided - no stepchildren.
 
Hi Gerrit,

Web forms doesn't have threading restrictions of Wind forms.
So, this brings the question whether we talk about win forms or web forms
 
Well, IMHO it is pretty obvious that he is talking about Windows Forms.

Regards,

Gerrit

Stoitcho Goutsev (100) said:
Hi Gerrit,

Web forms doesn't have threading restrictions of Wind forms.
So, this brings the question whether we talk about win forms or web forms

--

Stoitcho Goutsev (100) [C# MVP]


Gerrit Schunk said:
Try sometihng like this (just types here, not tested):

Private WebServiceProgress As ProgressDialog

Private Sub Button_Click()

WebServiceProgress = New ProgressDialog
WebServiceProgress.MaximumProgress = 100
Dim WebServiceThread As New Thread(AddressOf WebServiceBackground)
WebServiceThread.Start()
WebServiceProgress.ShowDialog
WebServiceProgress.Dispose()
WebServiceProgress = Nothing

End Sub

Private Sub WebServiceBackground()

Do While WebServiceProgress Is Nothing OrElse Not WebServiceProgress.Visible
Application.DoEvents
Loop

' Do work here and update progress...
WebServiceProgress.IncrementProgress()

' When done close progress dialog.
WebServiceProgress.Close()

End Sub

HTH,

Gerrit
the
displaying
 
It is possible to have your main form create a new thread and then create a new form on this thread. But the new form should not have it's parent property set to the main form since this will give you the kind of problems that Stoitcho Goutsev writes about in another post.

Some may argue that you should keep all UI on the same thread and they may indeed be right. So a better solution might be to fire up a new thread to do the web service call while the main thread shows a "Please wait" form. Using an asynchonous delegate you can provide a callback when the web service call is finished and then close the form. Just remember that you cannot call a form directly from another thread - you need to use Form.Invoke instead to syncrhonize the call.

Regards, Jakob.
 
Back
Top