.net Process.kill似乎不起作用
下面的代码挂起在最后对WaitForExit的调用中。如果我取消1秒长的睡眠,它会干净地终止。有人能告诉我该怎么做,这样在我打电话给Kill后,这个过程会很快消失吗?非常感谢.net Process.kill似乎不起作用,.net,f#,.net,F#,下面的代码挂起在最后对WaitForExit的调用中。如果我取消1秒长的睡眠,它会干净地终止。有人能告诉我该怎么做,这样在我打电话给Kill后,这个过程会很快消失吗?非常感谢 let processStartInfo = System.Diagnostics.ProcessStartInfo("c:/cygwin/bin/bash.exe", "-c yes") processStartInfo.CreateNoWindow <- true processStart
let processStartInfo = System.Diagnostics.ProcessStartInfo("c:/cygwin/bin/bash.exe", "-c yes")
processStartInfo.CreateNoWindow <- true
processStartInfo.UseShellExecute <- false
processStartInfo.RedirectStandardOutput <- true
processStartInfo.RedirectStandardInput <- false
processStartInfo.RedirectStandardError <- true
use proc = new System.Diagnostics.Process ()
proc.StartInfo <- processStartInfo
let f _ = ()
proc.OutputDataReceived.Add f
proc.ErrorDataReceived.Add f
if not (proc.Start()) then
failwithf "Could not start"
proc.BeginErrorReadLine ()
proc.BeginOutputReadLine ()
// the process terminates fine without this
System.Threading.Thread.Sleep (1000)
printf "Waiting to die"
proc.Kill () // this does not seem to work
proc.CancelOutputRead ()
proc.CancelErrorRead ()
proc.WaitForExit() // execution gets stuck here, apparently forever
我不知道F,但是这个代码有一些非常奇怪的东西;Read是一个阻塞调用,因此如果您想等待重定向到的内容完成,则必须使它们异步或调用.ReadToEnd。我将使用proc.Dispose或将其放在C中的using块中,而不是调用proc.kill,这应该在WaitForExit之后完成 看看我的答案
另外请注意,如果同时重定向stdOut和stdErr,则必须至少使其中一个异步。非常感谢,我认为我没有使用进程。请阅读?在任何情况下,stdout和stderr读取都是异步的?你确定杀戮应该在waitforexit之后进行,而不是相反吗?[注意:一旦proc离开作用域,use块将调用Dispose。我怀疑我可能不应该在进程仍在运行时调用Dispose?]我接受了这个回答,这是出于礼貌。如果你有同样的问题,请参阅我对H Passant评论的回复。谢谢@Joe,但是如果你找到了自己问题的答案,你应该自己发布答案。大约一天后,你可以接受自己的答案。这将有助于其他人。真正提出关键见解的是汉斯,我不想为此而自鸣得意。我不认为接受回答作为感谢贡献者时间的方式是违反规则的,即使在理想的世界中,接受别人的评论会更好。再次感谢。如果进程确实已终止,请使用任务管理器进行验证。WaitForExit不仅仅等待进程终止,它还等待所有重定向的输出被读取。除了Cygwin很古怪之外,很难猜测为什么没有发生。将Kill调用移到cancel调用之前可能会有所帮助。我发现您在第一部分是正确的-非常感谢。我认为问题在于,如果进程已经停止,WaitForExit将不会终止。这与M$文档中明确表示在kill之后调用它的说法直接矛盾。因此,修复方法是只提供一个超时,并在进程处于活动状态时重试。顺便说一句,取消的顺序似乎没有什么不同。