问题
I have a dotnet core 2.2 console app.
I hosted it as windows service.(Service name: "MyService1")
"MyService1" starts up another dotnet core WebAPI.
The problem is, how do I safely kill the WebAPI process when the "MyService1" is stopped?
Here is how I tried to do that but I can still see the process in the task manager.
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();
}
}
Is it possible to do that without using Kill() method?
回答1:
I'm not sure where you're starting your other WebAPI process from, nut you have 2 options:
Register to the
ProcessExit
event from yourProgram.cs
file and close the WebAPI process there, like this: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(); } }
Pass the service process id to the WebAPI process and monitor it from there, like this:
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 {} } }
回答2:
The problem you have there is that your webAPI task is actually a separate EXE, not integrated into the service. Unless the service has a way of interacting with it and requesting a graceful shut-down then you will have to terminate the EXE process in a manor that is decidedly not clean.
来源:https://stackoverflow.com/questions/56127334/net-core-console-app-as-windows-service-is-it-possible-to-safely-kill-executio