我有一个dotnet core 2.2控制台应用。
我托管了Windows服务。
服务启动了另一个dotnet core webapi。
问题是,当服务停止时,如何优雅地关闭WebAPI进程?
注意:我不想使用kill((方法。
示例代码:
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:ProjectbinDebugnetcoreapp2.2publishWebAPI.exe";
webAPI.Start();
}
catch (Exception e)
{
// Handle exception
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
// TODO: Add code to stop child process safely
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
从技术上讲,您可以简单地调用Process.Kill()
即可立即关闭该过程。但是,很多时候,这不是仅仅因为WebAPI可能处于重要操作的中间,而您无法真正判断这些动作何时发生,而Process.Kill()
并不是真正被视为"优雅"。p>最谨慎的是要告诉您您会喜欢的过程,以便在最早的方便下关闭它,然后允许WebAPI在其退出之前清理东西。如果您要探索更好的WebAPI,因为这样,您可以决定如何做到这一点。仅当绝对必要时调用Kill()
。
您当然可以这样做。有些想到的是定期检查并将CTRL C输入发送到WebAPI的插座。
public Task StopAsync(CancellationToken cancellationToken)
{
// send request to shut down
// wait for process to exit and free its resources
process.WaitForExit();
process.Close();
process.Dispose();
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
当然,如果这是异步,那么等待它在方法内部退出是没有意义的,因此您只需等待或检查该方法是否已退出此方法。
github上有很多有关此问题的线程,请考虑发布7426。
在此处找到该解决方案:startandStopdotnetCoreApp,程序的示例代码。CS是:
using System;
using System.IO;
using System.Diagnostics;
namespace StartAndStopDotNetCoreApp
{
class Program
{
static void Main(string[] args)
{
string projectPath = @"C:sourcereposStartAndStopDotNetCoreAppWebApplication";
string outputPath = @"C:TempWebApplication";
Console.WriteLine("Starting the app...");
var process = new Process();
process.StartInfo.WorkingDirectory = projectPath;
process.StartInfo.FileName = "dotnet";
process.StartInfo.Arguments = $"publish -o {outputPath}";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
process.Close();
process.Dispose();
process = new Process();
process.StartInfo.WorkingDirectory = outputPath;
process.StartInfo.FileName = "dotnet";
process.StartInfo.Arguments = $"{projectPath.Split(@"")[projectPath.Split(@"").Length - 1]}.dll";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
Console.WriteLine("Press anything to stop...");
Console.Read();
process.Kill();
}
}
}
如果这不是您要寻找的内容,请搜索上述线程以获取更多方法,它提供了很多。
也许可以使用System.Diagnostics.Process
类的CloseMainWindow
方法?当我正在寻找一种将WM_Close消息发送给C#的过程的方法时,我偶然发现了它。
编辑:
CloseMainWindow
如果主窗口被"阻止",例如通过打开的模态窗口或对话框。
您可以研究将WM_Close或WM_DESTROY消息发送到您的应用程序流程的策略。但是我不能保证它是否会按照您想要/期望工作。我很长一段时间没有使用这种Windows消息功能。