Консольное приложение .net Core - у сигнала на выходе время остановки - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть несколько консольных приложений, которые должны быть построены, и все они работают под названием «Работа». Это будут длительные процессы - никогда не заканчивающиеся, и они постоянно работают.

Имея это в виду, я надеюсь создать общий способ размещения этих рабочих мест. Каждое из них будет консольным приложением, но вместо того, чтобы использовать что-то вроде Console.Read (), чтобы остановить завершение консольного приложения, я собирался использовать ManualResetEventSlim, чтобы заблокировать завершение процесса.

Я придумал общий интерфейс, который будет реализовано в каждом консольном приложении, и затем его можно будет запускать обычным способом. Следующим образом:

public interface IHostedProcess
{
    void Starting();
    void Run();
    void Stopping();
}

Это означает, что я могу реализовать общий способ размещения процессов с помощью методов запуска, запуска и остановки:

public class ProcessHost
{
    ManualResetEventSlim keepAliveEvent = new ManualResetEventSlim();

    public void Run(IHostedProcess hostedProcess)
    {
        hostedProcess.Starting();

        AssemblyLoadContext.Default.Unloading += async ctx =>
        {
            hostedProcess.Stopping();
            keepAliveEvent.Set();
        };

        hostedProcess.Run();
        keepAliveEvent.Wait();
    }
}

И простой пример класса, который реализует интерфейс IHostedProcess и может быть запущен в консольном приложении:

public class MyHostedProcess : IHostedProcess
{
    public void Starting()
    {
        Console.WriteLine("Job starting");

        // Call my custom code here...
    }

    public void Run()
    {
        Console.WriteLine("Job running");

        // Call my custom code here...
    }

    public void Stopping()
    {
        Console.WriteLine("Job stopping1");

        // Call my custom code here...
    }
}

Оставив код моего консольного приложения в следующем виде:

public static void Main(string[] args)
{
    try
    {
        var mp = new MyHostedProcess();

        var ph = new ProcessHost();
        ph.Run(mp);
    }
    catch (Exception e)
    {
        Console.WriteLine("Something went wrong! " + e.Message);
        throw;
    }
}

Вывод выглядит следующим образом:

enter image description here

Затем нажмите «X», чтобы остановить процесс:

enter image description here

И мы видим сообщение «остановка»:

enter image description here

Так что все это прекрасно работает до определенного момента - когда я пытаюсь выполнить длительный процесс выключения в MyHostedProcess.Stopping, кажется, что он жестко закрывается и не ждет, пока этот процесс завершится. Пример, измените процесс «Остановка» следующим образом:

public void Stopping()
{
    Console.WriteLine("Job stopping first");

    // Call my custom code here...
    Thread.Sleep(20000); // Doesnt seem to wait this long...
    Console.WriteLine("Job stopping second"); // Never see this!
}

Я никогда не вижу вывода «Остановка второго задания», поскольку консольное приложение, кажется, останавливается через 10 секунд или около того. Что я делаю неправильно? Как мне более корректно справиться с завершением работы и гарантировать, что я смогу завершить работу до закрытия приложения? Может быть, есть способ сделать это "из коробки", который я пропустил?

Спасибо за любые указатели заранее!

...