我有许多需要运行“ Jobs”的控制台应用程序。它们将是长期运行的过程-永无止境,并且会不断地工作。
考虑到这一点,我希望构建一种通用的方式来托管这些工作。每个都将是一个控制台应用程序,但是我没有使用Console.Read()之类的东西来停止控制台应用程序的完成,而是要使用ManualResetEventSlim阻止该过程完成。
我想出了每个控制台应用程序都将实现的通用接口,然后可以以通用方式运行它。如下:
public interface IHostedProcess
{
void Starting();
void Run();
void Stopping();
}
这意味着我可以使用start,run和stop方法来实现托管进程的通用方法:
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秒钟左右后就很难停止。我究竟做错了什么?如何更好地处理关机并确保我可以在应用关闭之前完成所有关机工作?也许有一种方法可以让我错过的“开箱即用”的操作?
感谢您提前提出任何建议!