views:

277

answers:

3

In a program in c# I have 2 threads apart from the main thread. When the user closes the form I want to terminate one of the threads from the main thread. How do I go about doing so?. Please provide me with the code if possible.

+1  A: 

If you want to kill off a thread you have started yourself I would suggest holding a reference to it, such as a private field. When the application (or thread) is finishing off you can simply call Thread.Abort() on that thread.

For example:

private Thread _myWorker;

void doSomething()
{
    _myWorker = new Thread(...);
    _myWorker.Start();
}

void killWorker()
{
    _myWorker.Abort()
}

You should note that then you call Abort() on the thread it will raise a ThreadAbortException which you should catch within your worker code and handle to cleanup etc. For more details see Thread.Abort

Additionally when your application shuts down its main thread (the message loop, aka Application.Run) the child threads will also be shut down.

Matthew Savage
Child threads will only be shut down automatically if they're background threads. Foreground threads can live on after the main thread has shut down.
Jon Skeet
+3  A: 

Please don't use Thread.Abort as recommended by the other answers so far, unless you want your program to be in an unknown state (see articles by Ian Griffiths and Chris Sells for more info). If closing the form should actually be killing the app, you're probably okay - but in that case I'd recommend just using background threads anyway, which will automatically die when all foreground threads have terminated.

From Joe Duffy's "Concurrent Programming in Windows":

There are two situations in which thread aborts are always safe:

  • The main purpose of thread aborts is to tear down threads during CLR AppDomain unloads. [...]
  • Synchronous thread aborts are safe, provided that callers expect an exception to be thrown from the method. [...]

All other uses of thread aborts are questionable at best. [...] While thread aborts are theoretically safer than other thread termination mechanisms, they can still occur at inopportune times, leading to instability and corruption if used without care.

(Synchronous thread aborts are when the thread aborts itself, rather than being aborted by another thread.)

For graceful shutdown (without risking getting into odd states) use a flag which is set periodically from the form and checked from the other threads - taking the memory model into account (e.g. either making the flag volatile or using a lock each time you test or set it). See my article on the topic for an example.

Jon Skeet
To close the form I have the corresponding event.I have named the thread that I wish to terminate as SecondThread.However I am unable to call SecondThread.Is there something I am missing here.Moreover if there is anyway by which a thread can abort itself that would simplify things because i prefer using the concept of flags as you have pointed out.
Avik
You just make sure that it has access to a shared piece of data, and that it polls it regularly to see whether or not it should shut down. Of course, you can only do this if you control what the thread's doing yourself.
Jon Skeet
This is quite subjective - if your threads are for a single unit of work then calling Thread.Abort() shouldn't leave it in a dirty state (provided you handle the abort properly). If you have a thread which is then calling out to lot of other methods then it gets messier. Its really a case of looking at what you are doing and determining the best approach.
Matthew Savage
"Provided you handle the abort properly" is the difficult bit - and likely to be harder than just making the thread shut down gracefully in the first place. While it's *somewhat* subjective, I think it's worth listening to the advice of true experts like Joe Duffy. Why take chances with something as tricky as asynchronous aborts?
Jon Skeet
+1  A: 

Killing threads from other threads is almost always a bad idea. The correct way to do it is to signal the thread to terminate and then wait for it.

That's because threads should be totally responsible for their own resources as much as practicable, and that includes their lifetime.

It doesn't need to be complicated, a simple variable which can be set by any thread and is read by another thread periodically will do (this isn't really in any language but you should get the idea if you know C):

int exitThread1 = false;
static void Thread1 (void) {
    while (!exitThread1) {
        // do stuff
    }
}
static void mummyProc (void) {
    int tid1 = startThread (Thread1);
    // dum de dum de dum ...
    exitThread1 = true;
    joinThread (tid1);
}
paxdiablo