Utilize ASP.NET Core Application Lifetime Events
At times you need to know when your ASP.NET Core web application is being
started and shutdown. One of the lesser known features of ASP.NET Core is the
IApplicationLifetime interface that allows you to wire some logic when such
application lifetime events occur. This article briefly discusses the
IApplicationLifetime interface and its functionality.
IApplicationLifetime interface
The IApplicationLifetime interface comes from Microsoft.AspNetCore.Hosting.
This interface exposes certain useful members :
- ApplicationStarted : This property can be used to hook
a callback that is executed when an application host is started.
- ApplicationStopping : This property can be used to hook
a callback that is executed when an application host is about to stop. Some
requests might be pending at this stage.
- ApplicationStopped : This property can be used to hook
a callback that is executed when an application has been stopped. All the
requests are complete at this stage.
- StopApplication() : This method allows you to shutdown
an application programmatically.
You might use these callbacks to flush out logs or send some notifications.
These three properties are actually CancellationTokens and allow us to register
Action callbacks. Remember that StopApplication() should be used with
caution after evaluating the consequences as it shuts down the current
application.
The IApplicationLifetime is registered with the DI container. You can inject
it in Configure() or some controller.
Ok. Let's create a simple ASP.NET Core MVC application that illustrates the
usage of these properties and method. As an example we will log messages in a
text file to confirm that a particular callback has been called.
Handling ApplicationStarted, ApplicationStopping, and ApplicationStopped
Create a new ASP.NET Core MVC application and open the Startup class. Then
add the following code to the class, ConfigureServices(), and Configure()
method:
private IHostingEnvironment env;
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
this.env = env;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvcWithDefaultRoute();
}
The Configure() method receives an object of IHostingEnvironment. We store it
in a private variable for later use. We need this object because we want to
compute the log file path in the callback methods.
Now, modify the Configure() method signature to include IApplicationLifetime
as shown below :
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
IApplicationLifetime lifetime)
{
...
...
}
Once you inject IApplicationLifetime into Configure() method you can wire the
callbacks discussed earlier. The following code shows how:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
IApplicationLifetime lifetime)
{
this.env = env;
...
...
lifetime.ApplicationStarted.Register(OnAppStarted);
lifetime.ApplicationStopping.Register(OnAppStopping);
lifetime.ApplicationStopped.Register(OnAppStopped);
app.UseMvcWithDefaultRoute();
}
The three properties namely ApplicationStarted, ApplicationStopping, and
ApplicationStopped allow you to register callbacks. This is done using the
Register() method. The three callbacks - OnAppStarted(), OnAppStopping(), and
OnAppStopped() are shown below :
public void OnAppStarted()
{
string path = $"{env.WebRootPath}/AppLog.txt";
string contents = $"App started at {DateTime.Now}";
File.AppendAllText(path, contents);
}
public void OnAppStopping()
{
string path = $"{env.WebRootPath}/AppLog.txt";
string contents = $"App stopping at {DateTime.Now}";
File.AppendAllText(path, contents);
}
public void OnAppStopped()
{
string path = $"{env.WebRootPath}/AppLog.txt";
string contents = $"App stopped at {DateTime.Now}";
File.AppendAllText(path,contents);
}
The callback method shown above simply log messages with timestamp to a text
file named AppLog.txt.
To test the application, run it and then after some time close it using the
system tray (IISExpress) or by pressing Ctrl + C in the console window
(Kestrel).


This will trigger the graceful shutdown of the application and the events
will be raised accordingly. The following figure shows the log messages after a
sample run of the application :

Stopping an application programmatically
In the preceding application run you initiated the application shut down
manually from system tray or console window. You can also stop an application
using StopApplication() method of IApplicationLifetime.
Consider the following view that allows you to do that with a click of a
button :

The view outputs a timestamp stored in IMemoryCahche. We do this just to
confirm that the application has been stopped and IMemoryCache is emptied.
To modify the application open the Startup class and add this line to
ConfigureServices().
services.AddMemoryCache();
Then open the HomeController and inject IApplicationLifetime and IMemoryCache
into the constructor :
private IApplicationLifetime lifetime = null;
private IMemoryCache cache = null;
public HomeController(IMemoryCache cache,
IApplicationLifetime lifetime)
{
this.cache = cache;
this.lifetime = lifetime;
}
Then write the Index() action as follows :
public IActionResult Index()
{
if (cache.Get("timestamp") == null)
{
cache.Set<string>("timestamp",
DateTime.Now.ToString());
}
ViewBag.TimeStamp = cache.Get<string>("timestamp");
return View();
}
The Index() action simply checks whether an entry named timestamp exists in
the IMemoryCache or not. If it doesn't exist, a new entry is added
otherwise the existing entry value is assigned to the ViewBag.Message.
Clicking the Stop Application button calls the Stop() action of
HomeController. The Stop() action is shown below :
[HttpPost]
public IActionResult Stop()
{
lifetime.StopApplication();
return new ObjectResult
("Application stopped successfully!");
}
The Stop() action calls StopApplication() method of IApplicationLifetime.
This causes the application shutdown. The action also returns a message to the
browser accordingly.
If you run the application and click on the Stop Application button you will
see the log entries in the AppLog.txt as before and the browser will show :

If you hit the application URL by opening a new tab, the application will be
started again and you will get a new entry in the IMemoryCache (since the cache
got emptied with the app shutdown).
That's it for now! Keep coding!!