以下代码用于从.net执行外部进程,如果在一定时间后没有终止,则将其终止。用于测试的特定过程只会在stdout上打印出“y”的行。
kill操作成功,但此后进程仍然存在。更复杂的是,调用CancelOutputRead会停止输出而不会在结尾产生通常的null,因此没有干净的方法知道输出何时是最终的(并且可以处理)。
我想知道如何正确地终止进程,以及如何找出它何时完成异步输出。非常感谢。
use proc = new System.Diagnostics.Process ()
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
let report (name:string) (value:System.Diagnostics.DataReceivedEventArgs) : unit =
let value = value.Data
if value = null then
printf "%s: NULL\n" name
else
printf "%s: %s\n" name value
proc.StartInfo <- processStartInfo
proc.OutputDataReceived.Add (report "stdout")
proc.ErrorDataReceived.Add (report "stderr")
if not (proc.Start ()) then
failwithf "Could not start process"
proc.BeginOutputReadLine ()
proc.BeginErrorReadLine ()
let res = proc.WaitForExit (100)
printf "WaitForExit returned %O\n" res
while not proc.HasExited do
proc.Kill ()
printf "Waiting 10s\n"
System.Threading.Thread.Sleep 10000
printf "Cancelling\n"
proc.CancelErrorRead ()
proc.CancelOutputRead ()
printf "Done cancelling\n"
System.Threading.Thread.Sleep 3000
()
我得到以下输出:
WaitForExit returned False // A higher timeout produces lots of "y" before here
stdout: y
Waiting 10s // kill has "succeeded" by now
stdout: y
stdout: y
stdout: y
stdout: y
<thousands of "y" lines left out>
Cancelling // oh well, lets just stop listening if it won't die
Done cancelling
stdout: y // this is bad, I want to be processing the output now