threads and GUI update

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

Guest

Background:
My GUI has multiple screens but only one is visible at a time so when I
change screens I hide the first one and show the second one. There are many
elements on each screen that need to be updated and this is done in a
separate update thread that is shared between the screens. Each screen has
an update function and when the screen is switched I call the new update
function the next iteration of the update thread.
1) Is there any reason why I can’t update a GUI element on a screen that is
hidden? I get an ObjectDisposedException when I try to this. The control’s
hwnd still exists so I don’t see what the problem is. Right now I just catch
and ignore this exception.
2) What can block an Invoke((MethodInvoker)delegate() call? Sometimes when
I’m switching screens my thread will freeze and in the debugger I can see it
is stuck on this line.

Thanks,
Jeff
 
Background:
My GUI has multiple screens but only one is visible at a time so when I
change screens I hide the first one and show the second one. There are many
elements on each screen that need to be updated and this is done in a
separate update thread that is shared between the screens. Each screen has
an update function and when the screen is switched I call the new update
function the next iteration of the update thread.
1) Is there any reason why I can't update a GUI element on a screen that is
hidden? I get an ObjectDisposedException when I try to this. The control's
hwnd still exists so I don't see what the problem is. Right now I just catch
and ignore this exception.

Look at the stack trace of the exception to help identify what object
is disposed. I would not catch and ignore this exception. In almost
every scenario this exception indicates a bug. The problem is you're
(either directly or indirectly) calling a method on an object that has
already been disposed.
2) What can block an Invoke((MethodInvoker)delegate() call? Sometimes when
I'm switching screens my thread will freeze and in the debugger I can see it
is stuck on this line.

Invoke uses the UI thread's message loop to marshal the delegate and
then waits for it to be processed. I'd say it's likely that the
message loop is hung.

Can you post the shortest possible code that demonstrates both
problems?
 
Thanks for the advice Brian.
Actually the object the exception says is already disposed is the form I
have just hidden. This is strange because the Dispose() override is never
entered and when I show the form again (without calling any constructors) it
works fine. I get this exception when starting (or within?) a invoked
delegate.
I just feel there is something basic I don’t understand about the GC.

Jeff
 
I don't know, but something doesn't sound right with the "Each screen has an
update function and when the screen is switched I call the new update
function the next iteration of the update thread."

The first thing that came to mind when I read your post was the observer
pattern, where the object doing all the work is the subject and the various
screens are the observers.

The subject exposed an event "Updated" or something like that, and the
observers subscribe to that event. As the subject iterates over it's work,
it fires Updated as designed.

Does that describe your setup, or does it not apply for your situation?

Ron
 
Thanks for the idea Ron. Yes I would say that my screens basically follow
the observer pattern each with around 100 independent GUI represented
observers per screen. In the past with C++ I always done this (successfully)
with threads rather than events because of what I viewed as the greater
reliability and efficiency of threads.

I will think if it is worthwhile to change but I'm still curious as to the
root cause of the current problem. Another potential issue is if there is
any effect from hiding a screen in the middle of an RPC call. I don't think
there should be.

Jeff
 
The solution I ended up was to not hide the screens during the update,
waiting until the current update was complete. Since the update also
involves RPC (remoting) I guess that somehow the hiding the form messes up
the remote call.
One insight that helped my understanding was reading that Invoke =
SendMessage, BeginInvoke = PostMessage. Now I understand what Invoke is
doing a bit better.

Jeff
 
Back
Top