Консольное приложение ядра .net в качестве службы Windows. Можно ли безопасно завершить выполнение запущенного процесса без использования метода Kill ()? - PullRequest
2 голосов
/ 14 мая 2019

У меня есть консольное приложение dotnet core 2.2.
Я разместил его в качестве службы Windows. (Имя службы: "MyService1")
"MyService1" запускает другое ядро ​​dotnet WebAPI.
Проблема в том,Как безопасно завершить процесс WebAPI, когда MyService1 остановлен?

Вот как я пытался это сделать, но все еще вижу процесс в диспетчере задач.

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:\Project\bin\Debug\netcoreapp2.2\publish\WebAPI.exe";
            webAPI.Start();
        }
        catch (Exception e)
        {
            // Handle exception
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // TODO: Add code to stop child process safely
        webAPI.Close();  

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

Возможно ли это сделать без использования метода Kill ()?

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Я не уверен, откуда вы запускаете ваш другой процесс WebAPI, но у вас есть 2 варианта:

  1. Регистрация на событие ProcessExit из вашего файла Program.csи закройте там процесс WebAPI следующим образом:

    class Program
    {
        static Process webAPI;
    
        static async Task Main(string[] args)
        {
            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
    
            webAPI = new Process
            {
                StartInfo = new ProcessStartInfo("dotnet")
                {
                    UseShellExecute = false,
                    CreateNoWindow = true,
    
                    //If you want to run as .exe
                    FileName = @"C:\Project\bin\Debug\netcoreapp2.2\publish\WebAPI.exe",
    
                    //If you want to run the .dll
                    WorkingDirectory = "C:/Project/publish",
                    Arguments = "WebAPI.dll"
                }
            };
            using (webAPI)
            {
                webAPI.Start();
                webAPI.WaitForExit();
            }
        }
    
        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            webAPI.Close();
        }
    }
    
  2. Передайте идентификатор процесса службы в процесс WebAPI и оттуда отслеживайте его следующим образом:

    class Program
    {
        static async Task Main(string[] args)
        {
            try { }
            catch { }
            // Make sure you use a finally block.
            // If for any reason your code crashes you'd still want this part to run.
            finally
            {
                if (int.TryPasre(args[X], out parentProcessId))
                    MonitorAgentProcess(parentProcessId);
            }
        }
    
        static void MonitorAgentProcess(int parentProcessId)
        {
            try
            {
                Process process = Process.GetProcessById(parentProcessId);
                Task.Run(() => process.WaitForExit())
                    .ContinueWith(t => Environment.Exit(-1));
            }
            catch {}
        }
    }
    
0 голосов
/ 14 мая 2019

Проблема в том, что ваша задача webAPI на самом деле является отдельным EXE-файлом, не интегрированным в службу. Если у службы нет способа взаимодействия с ней и запроса на корректное завершение работы, вам придется прервать процесс EXE в особняке, который явно не чист.

...