I've seen people calls OS's ExitThread in managed applications via PInvoke to exit a managed thread, like this:

[DllImport( "Kernel32.dll")]
public static extern void ExitThread(int exitCode);

public static void Run ()
    // calling OS's ExitThread to exit the current thread
    ExitThread (0);

public static void Main ()
    ThreadStart threadStart = new ThreadStart(Run);
    Thread thread = new Thread(threadStart);

I guess when unmanaged code is ported to managed code, people tends to translate every system call to a PInvoke. But because CLR provides another layer over the OS, some low level system calls don't make sense in the managed world. ExitThread is one of them, because managed threads are not equivlent to OS's native threads. The above code is wrong for 2 reasons:

  1. CLR has some clean up work (like stack unwinding) to do when a managed thread exits. CLR knows a managed thread is exiting when the thread procedure (like threadStart) returns or a ThreadAbortException is thrown. Calling OS's ExitThread (or even worse, TerminateThread) would bypass all back out code on the stack (such as destructor and finally block) and leave the program in an unspecified state.
  2. There is no guarantee about how CLR maps a managed/logical thread to an OS/physical thread. For example, several managed threads could be mapped to one OS thread, calling ExitThread in one managed thread might kill other managed threads unintentionally.

IMHO, calling system's ExitThread in managed program is almost always a mistake. Instead, we could just call Thread.Abort.


This posting is provided "AS IS" with no warranties, and confers no rights.