Form Object Disposal Checking From Thread

M

Mike

Hello,

Ok I have 2 classes in my project, one is the main form and one is a
connection class, at a certain event on my main form a new instance is
made of the connection class, and a reference to the main form is passed
to its constructor.

The connection class opens up a new thread and starts doing work in it,
and adds collected data to the main form via a (cross-thread) control
invoking delegate.

The problem arises if the main form is closed while the thread is doing
work which involves using the delegate and adding data to the controls
on the main form. Basically i get an exception stating the main form has
been disposed and that the thread cannot access it.

So to prevent this, I process the main forms _FormClosing event, my code
in this event sets a boolean termination flag in the connection class to
true.
The idea being that the thread checks this flag to see if it should
terminate.

The problem is the thread is involved in a loop during the point of
closure and it dosnt catch the updated termination flag until the form
has been disposed by which time its too late.

The thread code thats busy looks like this:
Code:

do
{
if (terminate == true)
return -1;

else if (group_info != "-end-")
{
group_info = CSReader.ReadLine();
mform.Debug_Console_Add_Item(group_info);
}

} while (group_info != ".");


mform, is the reference to the main form, and this is the line that
throws the exception that the objects been disposed. If i add a
Thread.Sleep(2000) line into the top of the else if then it works, as it
catches the flag and returns with -1 as i want and avoids the exception.

So how can i prevent this? i.e Ideally I need the form to wait for a
signal from the thread saying its terminated before disposing, but if do
Thread.CurrentThread.Join() in the form closing method, it practically
puts it in an infinite loop and the line
mform.Debug_Console_Add_Item(group_info); cannot execute... So nothing
happens.

Anyone faced this problem before and know how to get around it? I need
to terminate the thread cleanly so my connection code can tidy up.

I know i could just call thread.abort() and process the exception, but
its not a very clean way of doing it.

Ive also tried checking the forms closing status inside the control
delegate, but im not having any luck as its either too soon or too late
Crying or Very sad

Thanks,
Mike
 
G

Guest

I would suggest you create events that the background thread would raise to
any subscriber (in this case, the Form). When the form closes it would
unsubscribe and the background thread need not care...

Otherwise, you might want to consider using a BackgroundWorker class, which
would accomplish the same thing (where the progress event would be subscribed
to by the Form and the background thread (the DoWork handler) would send data
via the event to the subscriber.
 
R

Raaj

Mike,

This appears to be more of a synchronization issue.

You are depending over the writes on a global variable to halt or
resume process of a secondary thread. While this way of processing in
general is common in multi threading, one however must be aware that
between reads an update can occur, by the time you read a global
variable and determined the processing logic chances are that another
thread may have written a value to the global variable.

A probable solution would be to consider double checking the
synchronizer (as below) and also ensure that form is not disposed off.
The synchronizer per your example is "terminate" global variable

do
{
if (terminate == true) //Initial check
return -1;


else if (group_info != "-end-")
{
group_info = CSReader.ReadLine();
///double check another thread by now
has not updated the "terminate" variable
///and form is not dispsoed
if ((!terminate) && (!mform.Isdipsosed)) //verify again
mform.Debug_Console_Add_Item(group_info);
}


} while (group_info != ".");

I hope this helps

Raaj
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top