【问题标题】:How to restart asp.net core app programmatically?如何以编程方式重新启动 asp.net 核心应用程序?
【发布时间】:2016-07-07 10:16:43
【问题描述】:

如何以编程方式重新启动 asp.net 核心中的应用程序?

我想清除缓存,让应用重新进入启动。

【问题讨论】:

  • 只是为了更好地理解,为什么需要这个?
  • 我认为对我来说最常见的情况是通过一些管理视图来操作应用程序的设置。这些设置通常是在启动时启动的。
  • 我能想到的另一种用法是发布新版本并重启
  • 清除静态缓存?这对我来说似乎是一个完全合法的要求。

标签: asp.net-core


【解决方案1】:

在您阅读我的回答之前:此解决方案将停止应用程序并导致应用程序在下一个请求中重新进入启动。

.NET Core 2 有时您可能希望强制 ASP.Net Core 2 站点以编程方式回收。即使在 MVC/WebForms 时代,这也不一定是推荐的做法,但唉,有一种方法。 ASP.Net Core 2 允许注入一个IApplicationLifetime 对象,它可以让您做一些方便的事情。首先,它可以让您注册启动、关闭和关闭事件,类似于过去可能通过Global.asax 获得的事件。但是,它还公开了一种方法,允许您关闭站点(无需破解!)。您需要将其注入您的站点,然后简单地调用它。下面是一个控制器的例子,它的路由会关闭一个站点。

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";
        }

    }
}

来源:http://www.blakepell.com/asp-net-core-ability-to-restart-your-site-programatically-updated-for-2-0

【讨论】:

  • 我按照你说的做,但它没有关机!!
  • 它会停止应用程序,但在第一次请求后应用程序再次出现。这只是为了重新启动应用程序而不是永远关闭它。
  • 我试过了,它停止了应用程序并且没有重新启动它(我有点预料到,基于方法名称)
  • 我投反对票是因为ApplicationLifetime.StopApplication(); 只是停止了应用程序,并没有重新启动它
【解决方案2】:

更新Mirask's answer 更适合 .NET Core 2。

在 Program.cs 中,您将看到对 host.Run() 的调用。此方法有一个接受System.Threading.CancellationToken 的重载。这就是我正在做的事情:

public class Program {

    private static CancellationTokenSource cancelTokenSource = new System.Threading.CancellationTokenSource();

    public static void Main(string[] args) {

        var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

        host.Run(cancelTokenSource.Token);
    }

    public static void Shutdown() {
        cancelTokenSource.Cancel();
    }
}

然后,在我的控制器中,我可以调用Program.Shutdown(),几秒钟后应用程序就死了。如果它在 IIS 后面,另一个请求将自动启动应用程序。

【讨论】:

  • 这绝对是完美的,谢谢。关于由 IIS 托管时的处理,这比添加对 Microsoft.Web.Administration 的引用或修改 web.config 文件以欺骗 IIS 回收要好得多。
  • 小更新。我发现 Run(token) 方法在 .NET Core 2.0 中不再可用。我使用以下行来解决这个问题:.RunAsync(cancellationTokenSource.Token).GetAwaiter().GetResult();
  • 谢谢,自从更新以来我一直在想如何做到这一点。您应该将此作为答案。
  • @Schwarzie2478, @Chet 您是否尝试使用IApplicationLifetime.ApplicationStopping - 看起来调用Cancel 就足以开始关机了。
  • 我刚刚对此进行了测试,您确实可以使用IApplicationLifetime.StopApplication()。您想将此添加为答案吗?
【解决方案3】:

ASP.NET Core 3+

由于接受的答案是使用 IApplicationLifetime,它在 ASP.NET Core 3 以后已过时,因此新的推荐方法是使用位于 Microsoft.Extensions.Hosting 命名空间中的 IHostApplicationLifetime

在我的 Blazor 应用程序中,我可以使用以下代码:

@inject IHostApplicationLifetime AppLifetime

<button @onclick="() => AppLifetime.StopApplication()">Restart</button>

【讨论】:

  • 嗨@WΩLLE 可以从后端进行吗?我试过了,但它给了我一个 NullReference 异常......也许我做错了......我的应用程序使用了太多缓存,因此我想重新启动应用程序,但不知道如何通过代码释放缓存......是否可以使用您的解决方案?
【解决方案4】:

对于 .NET Core 2.2,您可以使用以下代码:

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();
        }
    }
}

例如,服务器关闭可以放在某些网页后面:

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 可能是这样的:

@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

【讨论】:

  • RunAsync 方法需要 CancellationToken 对象而不是 CancellationTokenSource,所以这段代码对我不起作用
  • 它专注于令牌? cancelTokenSource.Token ?
【解决方案5】:

以上解决方案都没有达到我想要的效果。所以这就是我想出的:

 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>();
            });
}

【讨论】:

  • 我使用了你的代码,它确实有效。我还在 Restart 方法之前调用了 StopApplication 。你在生产环境中使用过吗?
【解决方案6】:

如果您只是在开发场景中需要它,那么您可以使用dotnet-watch(用于 dotnet)或dnx-watch(用于 dnx)。

如果您希望您的应用程序在生产中重新启动,那么您必须实现类似于观察者所做的事情。您需要一个外部进程来终止并重新启动该进程。或者你需要你的应用程序启动一个自身的实例,然后杀死它自己。不幸的是,没有什么是开箱即用的。

【讨论】:

  • 这将是一个 hack,但应用程序能否以编程方式更改会触发应用重启的配置文件?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2016-09-26
  • 1970-01-01
  • 2016-03-09
相关资源
最近更新 更多