dotnet核心如何优雅地关闭子进程



我有一个dotnet core 2.2控制台应用。
我托管了Windows服务。
服务启动了另一个dotnet core webapi。
问题是,当服务停止时,如何优雅地关闭WebAPI进程?
注意:我不想使用kill((方法。

示例代码:

public class MyService : IHostedService, IDisposable
{
    private Timer _timer;
    static Process webAPI;
    public Task StartAsync(CancellationToken cancellationToken)
    {
        _timer = new Timer(
            (e) => StartChildProcess(),
            null,
            TimeSpan.Zero,
            TimeSpan.FromMinutes(1));
        return Task.CompletedTask;
    }
    public void StartChildProcess()
    {
        try
        {
            webAPI = new Process();
            webAPI.StartInfo.UseShellExecute = false;
            webAPI.StartInfo.FileName = @"C:ProjectbinDebugnetcoreapp2.2publishWebAPI.exe";
            webAPI.Start();
        }
        catch (Exception e)
        {
            // Handle exception
        }
    }
    public Task StopAsync(CancellationToken cancellationToken)
    {
        // TODO: Add code to stop child process safely
        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }
    public void Dispose()
    {
        _timer?.Dispose();
    }
}

从技术上讲,您可以简单地调用Process.Kill()即可立即关闭该过程。但是,很多时候,这不是仅仅因为WebAPI可能处于重要操作的中间,而您无法真正判断这些动作何时发生,而Process.Kill()并不是真正被视为"优雅"。p>最谨慎的是要告诉您您会喜欢的过程,以便在最早的方便下关闭它,然后允许WebAPI在其退出之前清理东西。如果您要探索更好的WebAPI,因为这样,您可以决定如何做到这一点。仅当绝对必要时调用Kill()

您当然可以这样做。有些想到的是定期检查并将CTRL C输入发送到WebAPI的插座。


    public Task StopAsync(CancellationToken cancellationToken)
    {
        // send request to shut down
        // wait for process to exit and free its resources
        process.WaitForExit();
        process.Close();
        process.Dispose();

        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

当然,如果这是异步,那么等待它在方法内部退出是没有意义的,因此您只需等待或检查该方法是否已退出此方法。

github上有很多有关此问题的线程,请考虑发布7426。

在此处找到该解决方案:startandStopdotnetCoreApp,程序的示例代码。CS是:

using System;
using System.IO;
using System.Diagnostics;
namespace StartAndStopDotNetCoreApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string projectPath = @"C:sourcereposStartAndStopDotNetCoreAppWebApplication";
            string outputPath = @"C:TempWebApplication";
            Console.WriteLine("Starting the app...");
            var process = new Process();
            process.StartInfo.WorkingDirectory = projectPath;
            process.StartInfo.FileName = "dotnet";
            process.StartInfo.Arguments = $"publish -o {outputPath}";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.Start();
            process.WaitForExit();
            process.Close();
            process.Dispose();
            process = new Process();
            process.StartInfo.WorkingDirectory = outputPath;
            process.StartInfo.FileName = "dotnet";
            process.StartInfo.Arguments = $"{projectPath.Split(@"")[projectPath.Split(@"").Length - 1]}.dll";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            Console.WriteLine("Press anything to stop...");
            Console.Read();
            process.Kill();
        }
    }
}

如果这不是您要寻找的内容,请搜索上述线程以获取更多方法,它提供了很多。

也许可以使用System.Diagnostics.Process类的CloseMainWindow方法?当我正在寻找一种将WM_Close消息发送给C#的过程的方法时,我偶然发现了它。

编辑:

CloseMainWindow如果主窗口被"阻止",例如通过打开的模态窗口或对话框。

您可以研究将WM_Close或WM_DESTROY消息发送到您的应用程序流程的策略。但是我不能保证它是否会按照您想要/期望工作。我很长一段时间没有使用这种Windows消息功能。

相关内容

  • 没有找到相关文章

最新更新