I have an application which does some background task (network listening & reading) in a separate Thread
. It seems however that the Thread is not being Terminated/Aborted when I close the application (click "x" button on titlebar).
Is that because the main Thread routine is while(true) {...}
?
What is the solution here? I was looking for some "interruption" flag for the Thread as the condition f开发者_如何转开发or "while" loop, but didn't found any.
The simplest way is to set the IsBackground property of the thread to true. This will prevent it from keeping the application open. An application terminates when all non-background threads terminate.
A more controlled way to stop the thread is to send it a message to shut down cleanly and ensure that it has terminated before letting your main thread terminate.
A method that I wouldn't recommend is to call Thread.Abort
. This has a number of problems, one of which is that it is not guaranteed to terminate the thread. From the documentation:
Calling this method usually terminates the thread.
Emphasis mine.
You can always force the issue:
class Program
{
public static void Main()
{
// ... do stuff
Environment.Exit(Environment.ExitCode);
}
}
The better approach is to set the Thread.IsBackground property to true as Mark already mentioned.
You could improve the while(true) loop to
void DoWork() {
while(!ShouldIQuitManualResetEvent.WaitOne(0)) {
// do something
}
IDidQuitManualResetEvent.Set()
}
A bit more graceful, short from the identifier names.
Well, instead of while(true)
, maybe you should:
while(appIsRunning)
{
}
And, at the closing event for your form,
appIsRunning = false;
thread.Join(2000);
where the last line is just to make sure you wait for the thread to cleanly finish. There are many other ways to force an end to a thread, but the problem is just there: you don't want to be forcing things, you want them to happen as naturally as possible.
After the join, you can check the status of thread to see if it has finished. If it doesn't, then (and only then) force its finish with a abort, and maybe notify your user (or write a log record) that something has not ended the way it should.
You can start your thread as:
ThreadPool.QueueUserWorkItem(DoStuff, input)
And it will be abort automatically with application close.
精彩评论