简体   繁体   English

优雅地终止C#进程无法正常工作

[英]Killing a C# process gracefully not working

I have an application that spawns multiples threads, one of which runs an iPerf executable which is used to monitor network reliability. 我有一个生成多个线程的应用程序,其中一个运行一个iPerf可执行文件,用于监视网络可靠性。 This process will run indefinitely, until the user attempts to close the window. 此过程将无限期运行,直到用户尝试关闭窗口为止。 This is where the issue comes in. I am trying to shut that process down gracefully so that the iPerf server does not get hung up, but I can not seem to get this working. 这就是问题所在。我试图正常关闭该进程,以使iPerf服务器不会挂断,但似乎无法正常工作。 I can shut it down just fine if I run the command manually from a command prompt and press Ctrl+c , but this does not seem to be easily done programmatically. 如果我从命令提示符处手动运行该命令并按Ctrl+c ,则可以将其关闭,但这似乎很难以编程方式完成。

I have tried multiple things, including process.Kill(); 我已经尝试了多种方法,包括process.Kill(); or process.StandardInput.Close() or even process.StandardInput.WriteLine("\\x3"); process.StandardInput.Close()或什至process.StandardInput.WriteLine("\\x3"); but none of these seem to send a graceful shutdown message to the process. 但是这些似乎都没有向进程发送正常关闭消息。 process.Kill(); causes the server to hang or fail to start up the next time, and the other two options do not stop the server at all. 导致服务器下次挂起或无法启动,而其他两个选项根本无法停止服务器。 But the manual ctrl+c works just fine. 但是手动ctrl+c可以正常工作。

Here is a snippet of my code: 这是我的代码片段:

iperf_proc = new Process();
iperf_proc.StartInfo.FileName = Application.StartupPath + ".\\iperf3.exe";
String argumentStr = " -c " + test_data.host + " -t 0";
iperf_proc.StartInfo.Arguments = argumentStr;
iperf_proc.StartInfo.UseShellExecute = false;
iperf_proc.StartInfo.RedirectStandardOutput = true;
iperf_proc.StartInfo.RedirectStandardInput = true;
iperf_proc.StartInfo.RedirectStandardError = true;
iperf_proc.Start();
iperfRunning = true;
iperf_proc.BeginOutputReadLine();
iperf_proc.BeginErrorReadLine();
while (false == iperf_proc.HasExited)
{
    if (true == processCancelled)
    {
        iperf_proc.StandardInput.Close(); // Doesn't Work!
        iperf_proc.StandardInput.WriteLine("\x3"); // Doesn't Work!
        iperf_proc.StandardInput.Flush(); // Doesn't Work!
    }
}
iperf_proc.WaitForExit();

Any help is greatly appreciated. 任何帮助是极大的赞赏。 Thank you! 谢谢!

UPDATE: 更新:

Based on the suggestion from Hans in the comment, I tried adding some stuff to the code to get the ctrl+c event sent over. 根据Hans在评论中的建议,我尝试向代码中添加一些内容以发送ctrl+c事件。

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
private enum CtrlEvents
{
     CTRL_C_EVENT = 0,
     CTRL_BREAK_EVENT = 1
}
private void closeBtn_Click(object sender, EventArgs e)
{
     processCancelled = true;
     //iperf_proc.CloseMainWindow();
     bool succeeded = GenerateConsoleCtrlEvent((uint)CtrlEvents.CTRL_C_EVENT, (uint)iperf_proc.Id);
}

This did not work at all. 这根本没有用。 The process is still running and it does the function added returns false. 该进程仍在运行,并且执行添加的函数将返回false。 I did check that the process id being passed matches the id of the process in task manager. 我确实检查了要传递的进程ID与任务管理器中的进程ID是否匹配。 That all is fine, but the GenerateConsoleCtrlEvent function returns false. 一切都很好,但是GenerateConsoleCtrlEvent函数返回false。 Any idea why this may be? 知道为什么会这样吗?

BeginOutputReadLine BeginOutputReadLine

Link describes how to do exactly what you are looking for in the example. 链接描述了如何精确执行您在示例中寻找的内容。

Why not use the built in Exited event to wait on so you are not blocking? 为什么不使用内置的Exited事件等待,以免阻塞? Especially if you are spawning multiple threads. 尤其是当您生成多个线程时。 If you want to block then WaitForExit() is available as well. 如果要阻止,则也可以使用WaitForExit()。

 if (true == processCancelled) { iperf_proc.StandardInput.Close(); // Doesn't Work! iperf_proc.StandardInput.WriteLine("\\x3"); // Doesn't Work! iperf_proc.StandardInput.Flush(); // Doesn't Work! } 

If you close the standard input, how are you going to write/flush it? 如果关闭标准输入,您将如何编写/刷新它?

After you have WaitForExit() you also need to Close() 在拥有WaitForExit()之后,您还需要关闭()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM