I have a number of console apps that need to be built that all run "Jobs". They will be long running processes - never ended, and they continually do work.
With that in mind, I'm hoping to build a generic way to host these jobs. Each will be a console app, but rather than using something like Console.Read() to stop the console app finishing, I was going to use ManualResetEventSlim to block the process from finishing.
I've come up with a generic interface that each console app will implement and then it can be run in a common way. As follows:
public interface IHostedProcess
{
void Starting();
void Run();
void Stopping();
}
This means I can implement a common way to host processes with a start, run and stop method:
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();
}
}
And a simple example of a class that implements the IHostedProcess interface and can be run in the console app:
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...
}
}
Leaving my console app code looking like this:
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;
}
}
Output is as follows:
Then click the "X" to stop the process:
And we see the "stopping" message:
So this all works fine up until a certain point - when I try to carry out a long running shut down process in MyHostedProcess.Stopping
it seems to have a hard shut down and not wait until that process is finished. Example, modify the "Stopping" process to this:
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!
}
I never see "Job stopping second" output as the console app seems to hard stop after 10 seconds or so. What am I doing wrong? How to I handle the shutdown more gracefully and guarantee I can complete any shutdown work before the app closes? Maybe there is a way to do this "out of the box" that I've missed?
Thanks for any pointers in advance!