我有一个dotnet core 2.2控制台应用程序。
我将其托管为Windows服务。
服务启动另一个dotnet核心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:\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
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
答案 0 :(得分:0)
在github上有很多关于此问题的主题,请考虑发布7426。
可在以下位置找到解决方案:StartAndStopDotNetCoreApp,program.cs的示例代码为:
using System;
using System.IO;
using System.Diagnostics;
namespace StartAndStopDotNetCoreApp
{
class Program
{
static void Main(string[] args)
{
string projectPath = @"C:\source\repos\StartAndStopDotNetCoreApp\WebApplication";
string outputPath = @"C:\Temp\WebApplication";
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();
}
}
}
如果这不是您想要的内容,请搜索提到的线程以寻求更多方法,它可以提供很多帮助。
答案 1 :(得分:0)
从技术上讲,您可以直接调用Process.Kill()
来立即关闭该过程。但是,很多时间不是唯一可行的方法,因为WebAPI可能处于重要操作的中间,并且您无法真正分辨出何时可能发生这些操作,并且Process.Kill()
并没有真正被认为是“优美的” “。
最明智的做法是告诉您您希望它 的过程,以便尽快关闭它,然后允许WebAPI在退出自身之前对其进行清理。如果您要设计的WebAPI更好,因为那样可以决定如何做。仅在绝对必要时才调用Kill()
。
您当然可以通过多种方式做到这一点。我想到的是一些套接字,这些套接字会定期检查并向WebAPI发送CTRL + C输入。
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;
}
当然,如果这是异步的,那么等待它退出方法内部就没有意义,因此您只需等待或检查它是否已退出该方法外部。
答案 2 :(得分:0)
也许可以使用CloseMainWindow
类的System.Diagnostics.Process
方法吗?当我在寻找一种从C#向其他进程发送WM_CLOSE消息的方法时,我偶然发现了它。
编辑:
CloseMainWindow
如果主窗口被“阻塞”,例如被打开的模式窗口或对话框“阻塞”,则似乎不起作用。
您可能会研究一种将WM_CLOSE或WM_DESTROY消息显式发送到您的应用进程的策略。但是我不能保证它是否会按您的期望/预期工作。我已经很长时间没有使用这种Windows Messages功能了。