OnLoad being called on non UI Thread

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi there,

I have a multithreaded UI (windows forms) and I have been very carefull that
all my forms and controls are created on the UI thread. However, I have
noticed the in some situations my overridden OnLoad method on one form is
being called on a ono UI thread.

My question is: Is it possible for the OnLoad method to be called on a
different thread other than the one that called .Show()? I'm trying to
establish whether my OnLoad method should be checking the InvokeRequired
event.

I suspect I have some kind of race condition as if I have break points in
the code before the .Show() then it seems fine!!

Thanks for your help
 
I found the problem. Shortly after showing the form (which does use the
correct UI thread) I was setting the Cursor property. I was setting this
property in a backgroud thread. Tut tut tut!!

I would still like to know the answer though to, will OnLoad ALWAYS be call
 
Hi Gravy,

Yes, Make sure that the thread that created the form in the first place
calls Show method. OnLoad has to be called in the same thread.
 
Does that mean what I *should* be doing is; when I make a call to a control
whether this is accessing a property or calling a method then I should always
use .Invoke? After all, how do I know what properties or methods update part
of the UI?

Putting this in to context: I have a user control which represents the UI
and I also have a controller class. The controller talks to the web service
asynchronously and when the ws call completes it gives the data to the user
control. Now, I'm thinking here that when the controller talks to the UI user
control (call any method or property on it) then it should do so through
..Invoke and .InvokeRequired. Does this sound a bit over the top?

Regards

Stoitcho Goutsev (100) said:
Hi Gravy,

Yes, Make sure that the thread that created the form in the first place
calls Show method. OnLoad has to be called in the same thread.


--
HTH
Stoitcho Goutsev (100) [C# MVP]

Gravy said:
I found the problem. Shortly after showing the form (which does use the
correct UI thread) I was setting the Cursor property. I was setting this
property in a backgroud thread. Tut tut tut!!

I would still like to know the answer though to, will OnLoad ALWAYS be
call
 
If this is true then I don't suppose there is an easy way of achieving this
is there? At the moment I thinking that I would need to declare a delegate
for each method signature I'm using on the control. Does anyone know of such
a list of definitions existing already?

Thanks

Gravy said:
Does that mean what I *should* be doing is; when I make a call to a
control
whether this is accessing a property or calling a method then I should
always
use .Invoke? After all, how do I know what properties or methods update
part
of the UI?

Putting this in to context: I have a user control which represents the UI
and I also have a controller class. The controller talks to the web
service
asynchronously and when the ws call completes it gives the data to the
user
control. Now, I'm thinking here that when the controller talks to the UI
user
control (call any method or property on it) then it should do so through
.Invoke and .InvokeRequired. Does this sound a bit over the top?

Regards

Stoitcho Goutsev (100) said:
Hi Gravy,

Yes, Make sure that the thread that created the form in the first place
calls Show method. OnLoad has to be called in the same thread.


--
HTH
Stoitcho Goutsev (100) [C# MVP]

Gravy said:
I found the problem. Shortly after showing the form (which does use the
correct UI thread) I was setting the Cursor property. I was setting
this
property in a backgroud thread. Tut tut tut!!

I would still like to know the answer though to, will OnLoad ALWAYS be
call
on the same thread that called Show().



:

Hi there,

I have a multithreaded UI (windows forms) and I have been very
carefull
that
all my forms and controls are created on the UI thread. However, I
have
noticed the in some situations my overridden OnLoad method on one form
is
being called on a ono UI thread.

My question is: Is it possible for the OnLoad method to be called on a
different thread other than the one that called .Show()? I'm trying to
establish whether my OnLoad method should be checking the
InvokeRequired
event.

I suspect I have some kind of race condition as if I have break points
in
the code before the .Show() then it seems fine!!

Thanks for your help
 
It would probably be simpler to keep the Controller in the UI thread. If you
need a separate thread for the webservice, break that out into another
abstraction. You will probably have more interaction between the
Controller<-->UI than Controller<-->webservice.

Regards,
Frank Hileman

check out VG.net: www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor
 
I agree but I found a problem with this. When the controller require some
data from the web service it invokes the call using the Beginxxx method on
the proxy, i.e. asynchronously. Once the call returns the controller is
notified on a non UI thread. I don't know how to switch back to the
controllers thread without a control.invoke after all the controller is not
a control derived class.

Perhaps I should use the reference to the UI user control the controller has
to do the switch to the UI thread and assume the controller is on the UI
thread? What do you think?

Thanks for your help.
 
Sorry, another thought. Maybe I could use a reference to the MainForm to
switch back to the UI thread. The reason I thought of that is that the
controller may not have a valid UI when it asks the web service for the
data.

BTW, does anyone know of any tools that will highlight that fact that a non
UI thread is updating the UI??
 
I think you want the "Polling Call Pattern" in sample 4 on this page:
http://support.microsoft.com/default.aspx?scid=kb;en-us;315582#8

To determine if your call completed, start a windows forms timer when you
first make the call. In the timer tick event, check to see if completed.
Keep checking until it is completed, then do your work, stop the timer. You
will already be on the UI thread.

Regards,
Frank Hileman

check out VG.net: www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor
 
In this pattern it calls Thread.Sleep in between polling the IAsyncResult.
Won't this put the UI thread to sleep and hence give an unresponsive app? I
suppose you could call DoEvents in the loop!!

Graham
 
The Sleep is just an emulation of work. You do not need a Sleep, nor a loop.
Instead, start a Windows.Forms.Timer, and on the Tick event periodically
check to see if IsComplete. When complete, stop the timer and use the
results of your operation. You will already be on the UI thread.

Frank
 
I get it now Frank. Thanks for your help.

Frank Hileman said:
The Sleep is just an emulation of work. You do not need a Sleep, nor a
loop. Instead, start a Windows.Forms.Timer, and on the Tick event
periodically check to see if IsComplete. When complete, stop the timer and
use the results of your operation. You will already be on the UI thread.

Frank
 
Back
Top