How can I restart an app in asp.net core programmatically?
I want to clear cache and cause the application to re-enter the startup.
How can I restart an app in asp.net core programmatically?
I want to clear cache and cause the application to re-enter the startup.
Before you read my answer: This solution is going to stop the app and cause the application to re-enter the startup in the next request.
.NET Core 2
There may come a time when you wish to force your ASP.Net Core 2 site to recycle programmatically. Even in MVC/WebForms days this wasn't necessarily a recommended practice but alas, there is a way. ASP.Net Core 2 allows for the injection of an IApplicationLifetime object that will let you do a few handy things. First, it will let you register events for Startup, Shutting Down and Shutdown similar to what might have been available via a Global.asax back in the day. But, it also exposes a method to allow you to shutdown the site (without a hack!). You'll need to inject this into your site, then simply call it. Below is an example of a controller with a route that will shutdown a site.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace MySite.Controllers
{
public class WebServicesController : Controller
{
private IApplicationLifetime ApplicationLifetime { get; set; }
public WebServicesController(IApplicationLifetime appLifetime)
{
ApplicationLifetime = appLifetime;
}
public async Task ShutdownSite()
{
ApplicationLifetime.StopApplication();
return "Done";
}
}
}
Source: http://www.blakepell.com/asp-net-core-ability-to-restart-your-site-programatically-updated-for-2-0
Since the accepted answer is using IApplicationLifetime which became obsolete in ASP.NET Core 3 onwards, the new recommended way is to use IHostApplicationLifetime which is located in the Microsoft.Extensions.Hosting namespace.
In my Blazor application, I can use following code:
@inject IHostApplicationLifetime AppLifetime
<button @onclick="() => AppLifetime.StopApplication()">Restart</button>
For .NET Core 2.2 you can use following code:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using System.Threading;
namespace BuildMonitor
{
public class Program
{
private static CancellationTokenSource cancelTokenSource = new System.Threading.CancellationTokenSource();
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
host.RunAsync(cancelTokenSource.Token).GetAwaiter().GetResult();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
public static void Shutdown()
{
cancelTokenSource.Cancel();
}
}
}
And server shutdown could be placed for example behind some web page:
using System;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace BuildMonitor.Pages
{
public class StopServerModel : PageModel
{
public void OnGet()
{
Console.WriteLine("Forcing server shutdown.");
Program.Shutdown();
}
}
}
stopServer.bat could be for example like this:
@echo off
rem curl http://localhost:5000/StopServer >nul 2>&1
powershell.exe -Command (new-object System.Net.WebClient).DownloadString('http://localhost:5000/StopServer') >nul
exit /b 0
None of the solutions above did what I wanted. So that is what I came up with:
public class Program
{
private static CancellationTokenSource cts = new CancellationTokenSource();
private static string[] _args;
private static bool _restartRequest;
public static async Task Main(string[] args)
{
_args = args;
await StartServer();
while (_restartRequest)
{
_restartRequest = false;
Console.WriteLine("Restarting App");
await StartServer();
}
}
public static void Restart()
{
_restartRequest = true;
cts.Cancel();
}
private static async Task StartServer()
{
try
{
cts = new CancellationTokenSource();
await CreateHostBuilder(_args).RunConsoleAsync(cts.Token);
}
catch (OperationCanceledException e)
{
Console.WriteLine(e);
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}