Program freeze when updating control on background form

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

Guest

Hello all,

I am experiencing a problem with a compact framework program I am writing
where the program freezes if an attempt is made to update or read any of the
properties of controls on forms which are not visible (hidden behind forms
which have been opened on top of them). This is the specific order of events:

1. The user clicks on a button on one of my forms, which causes a new form
to be shown which monitors the progress of a web service call. The web
service call is performed in a separate thread.
2. This web service call collects some data from a remote service, and this
data is used to update some internal data structures, which are bound to GUI
components on the original form (TextFields in this instance though
potentially any common Control type). The data structures implement
IEditableObject to allow changes to be picked up by bound controls.
3. Changes to the data provokes the bound control to copy the changes,
raising one of the many changed events. In this case, a TextChanged event is
raised.
4. I have a TextChanged listener on the control that checks the contents of
the field to see whether it is valid or not. An invalid field has it's
background colour set to pink, a valid one to Color.Empty.
5. Attempting to set the colour on the control results in the program
freezing.

I have tried to fix the problem in various ways, including making the update
within an EventHandler delegate which is called through Control.Invoke, to no
avail. Even querying properties on the control (which I thought was supposed
to work even if you weren't within the correct thread for the control) causes
the hang - I thought that perhaps since the control wasn't visible (and hence
the Visible property should be false) that I could check the Visible property
and if false, not perform the colour update.

Is there anything inherently wrong with modifying the state of a control on
a form which is currently hidden behind one in front? I am currently trying
to see how I could change my code to defer handling the change events until
the form becomes visible again without some filthy hacks.

Any advice would be appreciated.
 
You mentioned Control.Invoke but it sounds like you did not use it properly.
*Any* method call to a Control has to be via Invoke. I suggest populating
with data offline/unbound data structure(s) and at the end use
Control.Invoke to pass them to the Form that will then update its appearance
based on the state given.

If you still think you have tried the Control.Invoke approach correctly,
post some code for review.

Cheers
Daniel
 
Here is the way in which I am using Control.Invoke:

Control control;

....

public bool isValid()
{
bool valid;
... calculate valid ...
if(valid) {
control.Invoke(new EventHandler(setBackColor));
}
}

private void setBackColor(object sender, EventArgs e)
{
control.BackColor = Color.Empty;
}

as mentioned in the first post, even querying the value of control.Visible
inside an EventHandler called through Invoke causes the program to freeze (so
it's not just trying to assign values).
 
Querying a value *is* calling a method hence there is no surprise there.

I am sure that is not all of your code. Post a small reproducible sample if
you want it to be looked at. In addition to my previous suggestion, I would
sprinkle the code with tracing statements to see exactly which method causes
the freeze.

Cheers
Daniel
 
Showing all the code related to the process outlined in my first post would
result in a few hundred lines scattered across a variety of classes, so I
don't think that would be beneficial. I managed to get this to work by moving
the data update code into the completion listener of my progress monitoring
form (a delegate hook that tells the calling class when the progress
monitored task has completed). This is a little messier as the data really
should be updated as part of the main "task" that goes along with issuing the
web service call.

I will see if I can produce a smaller, clearer example of the original
problem outside of the application I am developing (I cannot really post
anything other than paraphrased code from the application I'm developing as
it is commercial software I am writing for my employer, not a hobby project
that I would be happy to distribute source for). If this reproduces the
problem I'll post the code for review.
 
Back
Top