28

Sometimes application can't exit when I called Application.Shutdown, the UI was closed, but the process is still running. how to shutdown application with close all threads? does the Environment.Exit() could close all thread? or we should call Win32 API TerminateThread to do it?

Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87
Cooper.Wu
  • 4,335
  • 8
  • 34
  • 42

3 Answers3

24

Environment.Exit() is a more brutal way of closing down your application, yes. But in general, if you need to kill your application to make it close then I think you're looking at the problem in the wrong way. You should rather look into why the other threads aren't closing gracefully.

You could look into the FormClosing event on the main form and close down any resources that are hanging up the application, preventing it from closing.

This is how I have found resources hanging up the app.

  1. In debug mode, enable showing of threads. (This will allow you to see all the threads your application is running.)
  2. Close the application in the way that it does not close correctly.
  3. Press pause in Visual studio.
  4. Look at the threads list, and click on them to see where is the code they are hanging. Now that you can see what resources are blocking your application from closing, go to your FormClosing event and close/dispose them there.
  5. Repeat until the app closes correctly :)

Be aware that the threads list in debug mode will show some threads that are run but not under your control. These threads rarely have a name and when you click on them you get a message saying you have no symbols. These can be safely ignored.

One of the reasons for making sure your application is closing gracefully is that some resources (let's say a FileStream) are not done working, so using some API to force it to quit can make all sorts of "random" problems come in, like settings/data files not being written and so on.

zvizesna
  • 43
  • 8
EKS
  • 5,543
  • 6
  • 44
  • 60
  • thanks for your response, called 'Application.Shutdown' but process still running was not always happened, i have tried your way to found out which thread was running, but this bug was not re-produced... – Cooper.Wu May 31 '09 at 03:02
10
  1. You should NEVER call TerminateThread
  2. Make sure that all the threads that you spawn are mark as background, this way when you close the application it won't wait for them to complete.
gog
  • 1,220
  • 11
  • 30
Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87
  • Oh, awesome. I didn't know you could do #2. – Joel May 25 '09 at 06:48
  • 2
    IsBackground solved this issue for me. Very useful, surprised it isn't more widely known. – SouthShoreAK Sep 12 '13 at 22:42
  • Philosophical question (or maybe a dumb one): Why does it exist if we should NEVER call it? – alzaimar Mar 21 '19 at 10:49
  • @alzaimar : The function exists because there are very, very restricted cases when one may be forced to call it. The restricted cases are detailed in the [Remarks section of the TerminateThread function documentation](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminatethread#remarks). An I add, even these cases may be avoided, if the code was written better. So, the reason why this still exists may be: _historical_ and _compatibility_. – gog Nov 04 '20 at 10:03
4

As Shay said, NEVER call TerminateThread, TerminateThread kills just one thread without letting it clean up after itself this can lead to deadlocks and corruptions in other threads in the process.

TerminateProcess on the other had will kill the entire process and let the OS clean up, it's the fastest way to close a process - you just have to make sure you are not holding any resources the OS can't clean up (it also helps to close windows before calling TerminateProcess).

I think, but I haven't checked, that Environemnt.Exit calls TerminateProcess.

Application.Shutdown is very different, it doesn't immediately kill the process - it sends all the closing and shutdown notifications and waits for all the application's windows and threads close themselves.

Nir
  • 29,306
  • 10
  • 67
  • 103