У меня есть несколько консольных приложений, которые должны быть построены, и все они работают под названием «Работа». Это будут длительные процессы - никогда не заканчивающиеся, и они постоянно работают.
Имея это в виду, я надеюсь создать общий способ размещения этих рабочих мест. Каждое из них будет консольным приложением, но вместо того, чтобы использовать что-то вроде 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;
}
}
Вывод выглядит следующим образом:
Затем нажмите «X», чтобы остановить процесс:
И мы видим сообщение «остановка»:
Так что все это прекрасно работает до определенного момента - когда я пытаюсь выполнить длительный процесс выключения в 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 секунд или около того. Что я делаю неправильно? Как мне более корректно справиться с завершением работы и гарантировать, что я смогу завершить работу до закрытия приложения? Может быть, есть способ сделать это "из коробки", который я пропустил?
Спасибо за любые указатели заранее!