Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture shutdown command for graceful close in .NET Core

I'm porting to .NET core and the existing app has hooked the win32 call SetConsoleCtrlHandler to capture application close so that it can cleanly close off open database files and other orderly shutdown tasks.

I need to do the same in .NET core, and the only option I can see is with ASP.NET by hooking into IApplicationLifetime ApplicationStopping.Register. However that only captures Ctrl-C and does not work if the end user or system terminates the console app (eg. system reboot) which the win32 call will.

The other option is via AppDomain (AppDomain.CurrentDomain.ProcessExit) however AppDomain isn't available in dotnet Core.

Orderly app shutdown is important and I'm concerned about data corruption in the production system so need to implement something equivalent, and the new app will be running on a mix of Windows and Linux OS.

Have I missed a function in dotnet core to do this? Or do I have to re-implement the win32 shutdown hook and whatever is the equivalent on Linux?

like image 339
deandob Avatar asked Feb 04 '17 20:02

deandob


People also ask

How do I shutdown a NET Core Application?

This is equivalent of using Ctrl+C in the terminal running your application. Watch your application receive a shutdown signal. . NET Core by default uses a ConsoleLifetime class that is wired up by default and listens to this signal. But shutdown - what do you mean?

What is the meaning of graceful shutdown?

For example, you might want to not start writing to disk if you already know the application is about to shut down. To add this kind of functionality, extra code with the only responsibility to exit your application gracefully, is called graceful shutdown.

Is it possible to do graceful shutdown with SIGTERM?

@tkarpinski it is actually possible to do true graceful shutdown. I used Mono.Posix.NETStandard nuget package like that: It works fine and lets my requests in flight to successfully complete. The problem is it is a bit non standard and the "official" way to handle SIGTERM in .net core is to capture AssemblyLoadContext.Default.Unloading event.

How to shut down an application in Linux terminal?

Copy this process id. TERM here means SIGTERM, which means to - in a polite way - to ask the application to shutdown. This is equivalent of using Ctrl+C in the terminal running your application. Watch your application receive a shutdown signal. .


2 Answers

The AppDomain.CurrentDomain.ProcessExit event is now available in .NET Core 2.0, and I can confirm that it works fine on Linux. Before .NET Core 2.0, AssemblyLoadContext.Default.Unloading is probably a working alternative.

like image 163
Marc Sigrist Avatar answered Oct 21 '22 09:10

Marc Sigrist


If you can update to dotnet core 2.1 (or later) you should consider using the IHost interface for console apps and IHostedService for asp.net core apps (2.0 and upwards) which are designed for just this sort of thing - telling the framework you have background processes that need to be notified on shutdown.

More info at https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/

Admittedly you may need AppDomain.CurrentDomain.ProcessExit as well for the killed process scenario, but using IHost/IHostedService will give you more time for a graceful shutdown in most application shutdowns.

like image 36
alastairtree Avatar answered Oct 21 '22 10:10

alastairtree