Sleeping thread problem when closing app

  • Thread starter Thread starter Annette Miller
  • Start date Start date
A

Annette Miller

I use Thread.Sleep to cause my background threads to for 500ms. The
structure of the thread is:

do
{
...
-- code --
...
Thread.Sleep(500);
} while (!closing)

Now my problem is that occassionally when my application is exiting it just
hangs and won't close. In my FormClosing event I have the following code:

closing = true;
backgroundThread.Interrupt();
backgroundThread.Abort();

But it doesn't seem to stop the problem. And when the background thread
doesn't sleep the problem doesn't occur, but its not an option because CPU
usage is high if it doesn't sleep.

How do I fix this?
Cheers...
 
One of the possible solutions:
1. Create an AutoResetEvent or any other waitable object associated with the
thread.(It can be a member of your thread class).
....
public AutoResetEvent autoResetEvent;
....
2. Instead of Thread.Wait use AutoResetEvent.Wait.
....
} while (!autoResetEvent.Wait(500,false))
....
3. Before you want to exit the program e.g. in form close signal the event
instead of your interrupt and abort code.
....
backgroundThread.autoResetEvent.Set
....
 
Now my problem is that occassionally when my application is exiting it just
hangs and won't close.

1. Before starting the thread, do
backgroundThread.IsBackground = BackgroundThread
Now, when your main app stops, the thread will stop too without any fuss.
This will work fine in settings where you have no thread cleanup worries (the
thread is stopped aburuptly).

2. O'Reilly in ".Net Gotchas" advises against using most of the thread
methods. I agree owing to unexplainable intermittent flakiness. I use a
global boolean variable that is a shutdown flag. When my app wants to shut
down, it sets the flag to true and goes about its business. My threads are
obliged to examine the flag periodically, and if it is true, they cleanup and
shut down. This mechanism will work with non-background threads.
 
Concerning the global boolean flag, the question is how often do your thread
check it.

If it is often - it meens that you are using processor time for nothing and
it can not be used for other usefull tasks in your process and in other
processes. If you are checking the flag not very often - you'll need to wait
this period of time before the process will close after the flag is set.
To avoid this problem Windows has a mechanism of waitable objects (events
and other) and wait functions. When wait function is called thread sleeps
down untill one of it's arguments is signalled or the specified time is out.
 
Concerning the global boolean flag, the question is how often do your thread
check it.

A few times per second.
If it is often - it meens that you are using processor time for nothing and
it can not be used for other usefull tasks in your process and in other
processes. If you are checking the flag not very often - you'll need to wait
this period of time before the process will close after the flag is set.

Checking the flag a few times per second has never adversely affected either
response time or total cpu usage.
To avoid this problem Windows has a mechanism of waitable objects (events
and other) and wait functions. When wait function is called thread sleeps
down untill one of it's arguments is signalled or the specified time is out.

A boolean shutdown flag just sounded like the minimum change way for Annette
to get past her problem (assuming she could not just set .IsBackground=True).
However, I use (and like) waitable objects too. Perhaps a class containing
a manual reset event could be the basis for sleep functionality with demand
wakeup for shutdown or other purposes.
 
Hi,

Thanks for the reply. I had set IsBackground.

For some reason the code was sticking in methods where it needed to invoke,
and I have no idea why - basically in the IDE if I hit Break/Pause and
looked at what was still executing, my background threads were stuck off
somewhere in a method that was invoking, and yes the methods did check to
see if a shutdown was in progress too.

Using AutoResetEvent seems to have solved my problems.

Cheers guys.
 
Hi Annette,

Annette Miller said:
I use Thread.Sleep to cause my background threads to for 500ms. The
structure of the thread is:

do
{
...
-- code --
...
Thread.Sleep(500);
} while (!closing)

Now my problem is that occassionally when my application is exiting it just
hangs and won't close. In my FormClosing event I have the following code:

closing = true;
backgroundThread.Interrupt();
backgroundThread.Abort();

But it doesn't seem to stop the problem. And when the background thread
doesn't sleep the problem doesn't occur, but its not an option because CPU
usage is high if it doesn't sleep.

How do I fix this?
Cheers...

I think you should read about threading in .NET. Following link is a good one:
http://www.yoda.arachsys.com/csharp/threads/
In specific the following chapter is about 'graceful shutdown':
http://www.yoda.arachsys.com/csharp/threads/shutdown.shtml

Kind regards,
 
Back
Top