gpt4 book ai didi

c# - process.kill() 是否终止 WaitForExit() (没有时间限制)

转载 作者:太空狗 更新时间:2023-10-29 20:13:42 27 4
gpt4 key购买 nike

我有一个在后台运行并具有 WaitForExit() 的进程,因为持续时间可能会有所不同,我需要等到它完成。有时,我需要在它完成之前结束它并通过类事件触发 .Kill() 命令。 .HasExited 属性更改为 true 但代码从未通过 WaitForExit() 行。

public class MyProcess: Process
{
private bool exited;

public MyProcess()
{
...
}




public void Start(args...)
{

try
{
base.StartInfo.FileName = ...
base.StartInfo.Arguments = ...
base.StartInfo.RedirectStandardOutput = true;
base.StartInfo.UseShellExecute = false;
base.StartInfo.CreateNoWindow = true;
base.EnableRaisingEvents = true;
base.Exited += new EventHandler(MyProcessCompleted);
base.OutputDataReceived += new DataReceivedEventHandler(outputReceived);
base.Start();
this.exited = false;
base.BeginOutputReadLine();

while (!this.exited)
{
if ()
{
...
}
else
{

base.WaitForExit(); ---- after the process is killed, it never gets past this line.

}

...
}
}

catch (Exception ex)
{
...
}
}


private void MyProcessCompleted(object sender, System.EventArgs e)
{
exited = true;

...
}


private void outputReceived(object sender, DataReceivedEventArgs e)
{
...
}


//Subscription to cancel event
public void ProcessCanceled(object sender, EventArgs e)
{
...

if (!exited)
{
base.Kill();
}
}
}

\

更新:

我的流程启动基于 Java 的文件传输客户端并执行传输。该进程显示在任务管理器中,并且 Kill() 不会结束它。因为我并不真正关心结束进程而是需要我的程序转到下一个“任务”,所以我在 Kill() 之后添加了 Close(),这会释放 WaitForExit 并让我的代码“继续”。提前终止进程在我的应用程序中很少见,但我仍然需要它正常工作,因此必须执行此实现。

最佳答案

WaitForExit 是对操作系统的直接调用,以等待进程句柄发出信号。当进程终止时,WaitForExit 完成。 Kill 是对 TerminateProcess 的直接调用,这是一个不问任何问题的 kill。如果使用正确,WaitForExit 将在 Kill 完成后返回。

所以您的代码中还有一些其他错误。创建一个更简单的重现,您将看到问题消失。该错误隐藏在您代码的复杂性中。

或者,WaitForExit 确实返回了,但您没有注意到。或者,Kill 从未执行或失败。同样,简化代码将揭示问题。你能把它减少到 5 行复制吗?我怀疑你能,但如果你能,我会再看一遍。

试试这个:

Process p = Process.Start("notepad.exe");
Task.Factory.StartNew(() => { Thread.Sleep(1000); p.Kill(); });
p.WaitForExit();

更新:

在您指定的评论中,终止 ping 确实有效,但终止您的特殊进程则无效。造成这种情况的原因通常是不可取消的 IO。 Windows 内核会保留进程,直到所有 IO 完成。好消息是该进程最终会终止,并且在 Kill 返回后不会运行任何代码。坏消息是资源清理还没有完全完成。

您现在需要确保您的代码可以继续执行,尽管 WaitForExit 没有返回。为此,我会在 Kill 完成后设置一个 ManualResetEvent。您无需调用 WaitForExit,而是使用 Process.Handle 属性获取进程句柄,并等待两个可等待对象中的任何一个变为有信号。查看 WaitForExit 在内部执行的操作,了解您如何自己实现它(我将复制内部的 ProcessWaitHandle 类)。

一个更简单的解决方案是在循环中调用 WaitForExit(TimeSpan.FromMilliseconds(100)) 并每次检查 exited 标志。

关于c# - process.kill() 是否终止 WaitForExit() (没有时间限制),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18707150/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com