.net Process.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

下面的代码挂起在最后对WaitForExit的调用中。如果我取消1秒长的睡眠,它会干净地终止。有人能告诉我该怎么做,这样在我打电话给Kill后,这个过程会很快消失吗?非常感谢

    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之后调用它的说法直接矛盾。因此,修复方法是只提供一个超时,并在进程处于活动状态时重试。顺便说一句,取消的顺序似乎没有什么不同。