Why Does Environment.Exit() Not Terminate the Program Any More

Why does Environment.Exit() not terminate the program any more?

I contacted Microsoft about this problem and that seemed to have paid off. At least I'd like to think it did :). Although I didn't get a confirmation of a resolution back from them, the Windows group is difficult to contact directly and I had to use an intermediary.

An update delivered through Windows Update solved the problem. The noticeable 2 second delay before the crash is no longer present, strongly suggesting that the IsWindow() deadlock got solved. And the program shuts down cleanly and reliably. The update installed patches for Windows Defender, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll and wintrust.dll

Uxtheme.dll is the odd-duck out. It implements the Visual Styles theming API and is used by this test program. I can't be sure, but my money is on that one as the source of the problem. The copy in C:\WINDOWS\system32 has version number 6.2.9200.16660, created on August 14th, 2013 on my machine.

Case closed.

System.Environment.Exit(0) does not exit program

Press any key to continue

Like a comment above said already, this sounds a lot like what your IDE (presumably Visual Studio) would print out once the process has terminated. On my machine, I get this message when I run a console application without attaching the debugger to it, e.g. by starting it with Ctrl+F5. Once I press a key, the console window spawned by Visual Studio will close. This is expected behaviour.

Try running your program with the debugger attached, e.g. by pressing F5. Or start the program from a command prompt instead of starting it from your IDE. The message shouldn't be displayed then.

Note also that if you have a multi-threaded program, and there are non-background threads running, these can keep a process alive even though the main thread has terminated.

Will Environment.Exit(int) kill my application with treads running unmanaged code?

From the official Microsoft documentation, Environment.Exit:

Terminates this process and returns an exit code to the operating
system.

More usefully, the documentation goes on to state:

  • Exit always terminates an application
  • Exit terminates an application immediately, even if other threads are running

It sounds like Environment.Exit is perfectly sufficient for your needs.

What is the difference between Environment.Exit(0) and Environment.Exit(Environment.ExitCode)?

I've used both, and they seem to do the same thing.

As others have already noted, that's because the default value for ExitCode is 0.

So which one should I use?

Typically, if you call Exit(), you a) have a good reason for that and b) you want to terminate as soon as possible with all the disadvantages described in the remarks section.

Therefore you would

  • never call Environment.Exit(0); and instead let the void Main() method run to its end in a normal way.
  • never call Environment.Exit(Environment.ExitCode); because that would imply that the reason for the termination was set a while back.
  • call Environment.Exit(ERRORCODE);, likely with a meaningful constant instead of a magic number

So the real answer is: don't use it at all, if possible.

Instead you might want to try Window.Close() to close a single window or Application.Exit(), which closes all windows and gets you back to the Main() method and out of the Application.Run() method call.

If that's not sufficient to terminate your program and you still see it in Task Manager, it has a foreground thread running, e.g. a thread that saves the users work. You don't want to terminate that, because it could result in a corrupted file.

There is a concept of a boolean isRunning or _shouldStop variable to terminate threads.

If you don't know why your application is not terminating, attach a debugger and have a look at the callstack of the remaining threads.

Why is my c# console application hanging when I try to exit?

My thought based on what you are describing is that the network write operation to \\bbd is not completing.

If you want to log and exit, but exit is more important than logging, perhaps try something like this:

ThreadPool.QueueUserWorkItem(state => {
Thread.Sleep(2000);
Environment.Exit(0);
});
File.AppendAllText(@"\\bbd\FLog", "Halting: " + DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss") + "\n");

This way, your process will exit in 2 seconds no matter what; even if your log operation never completes.

A more elegant solution might quit as soon as the log operation completes OR after a timeout, but my code is just for an example

Environment.Exit doesn't close

Are you using any threads in the application ?
In case you are, make sure you stop all the threads before exiting the application.
I don't normally prefer the .abort command, but you can try using

th.Abort(); //th is the name of the thread

before you use Environment.Exit(0)

Environment.Exit takes long time to close the application

What's happening behind the scenes is quite clear if you understand how .NET applications work, and how Environment.Exit works.

In short, Environment.Exit is not the fastest way to exit an arbitrary application. It still waits for any pending finalizers to run (if they run fast enough, they only have 30 seconds total IIRC). If you're using e.g. sockets, it's perfectly possible that the finalizers take a few seconds to run.

The easiest way to check is of course to use the debugger - just Pause when doing the shutdown, and you'll see which threads are actually executing, and what it is they are executing.



Related Topics



Leave a reply



Submit