Abort a thread in Dispose()

michael_hk

Centurion
Joined
Nov 24, 2003
Messages
199
Location
Hong Kong
Hi guys,

I have built a multi-threaded User Control that is used inside a WinForm. Sometimes when I close the form I got exception. The exception is caused by the thread inside the user control, it is still running even the winform is closed.

Exception: Object reference not set to an instance of an object.

Since I am not allowed to touch the winform, I am planning to put myThread.Abort() inside the Dispose method of my user control.

Is it the proper way to kill the thread?

Thanks in advance.

Michael
 
Last edited:
The following code doesn't catch the exception

Code:
// Dispose method of my user control
protected override void Dispose( bool disposing )
{

	try
	{
		t.Abort(); // t is the thread
	}
	catch {}
	...
}
 
you would need to post reproduceable code, also, you don't invoke the base classe's dispose method

Visual Basic:
base.Dispose(disposing)
but I don't know if that's your intention.
 
Let me give more details about my user control.

Basically it only contains labels, datagrid, textboxes, buttons etc, all are ordinary winform controls. The reason it is multi-threaded is one of the textboxes is autoscrolling - it contains some announcements and the messages keep scrolling and self updating. Therefore I create a thread to keep the message moving

Code:
//what the thread does (just the idea)
while (true)
{
	CheckForUpdate();
	DisplayMessage(); 
	myThread.sleep(sometime); // keep the message moving in a reason pace
}
Ok, back to my Q. Here is my Dispose method.


Code:
protected override void Dispose( bool disposing )
{
	try
	{
		if ( t.IsAlive ) 
		{ 
			t.Abort(); 
		}
	}
	catch {}

	if( disposing )
	{
		if(components != null)
		{
			components.Dispose();
		}
	}
	base.Dispose( disposing );
}
All I want to do is to kill the thread properly so that there will not be any exception or at least I can catch it if it happens to occur.
 
Code:
//what the thread does (just the idea)
while (true)
{
	CheckForUpdate();
	DisplayMessage(); 
	myThread.sleep(sometime); // keep the message moving in a reason pace
              Application.DoEvents();
}


Code:
protected override void Dispose( bool disposing )
{
	try
	{
                             t.Abort();
                             //t.Join(); //if you want to wait for it to abort

	}
	catch {}

	if( disposing )
	{
		if(components != null)
		{
			components.Dispose();
		}
	}
	base.Dispose( disposing );
}
 
Why are you creating your own loop and not using a timer that fires every 0.1 sec or so? Has several advantages:
-you only have to stop the timer and not kill the thread.
-if your CheckForUpdate takes a variable amount of time (e.g. you have to get information from a database on the other side of the network or something), the updates are done infrequently as well. With a timer, you still have a fixed update interval.

Anyway, the ThreadAbortException (or any other exceptoin) will not be raised in your Dispose method, but in the while loop I think:
//what the thread does (just the idea)
while (true)
{
CheckForUpdate();
DisplayMessage();
myThread.sleep(sometime); // keep the message moving in a reason pace
}
The whole ThreadAbortException is a pretty funny exception as it keept being raised even if you handle it, but doesn't even generate a popup if you don't handle it ;).

And don't use the doevents statement, as there is no need. Upon the sleep the OS will automatically activate other threads.
 
Thanks for all the input.

Wile, Yes, timer is an alternative. But as my thread is quite busy (keep appending text to the textbox to make in scrolling, and also need to check the database to get any update), I intentionally do all these with a separate thread rather than in the main thread (if use a timer).

Ok, finally someone suggested me to

1. Override OnHandleDestroyed event of my user control
2. Set IsBackground property of the thread to true

So far my program hasn't crashed since I made these changes. :p
 
Back
Top