如何在.net中杀死超时进程

时间:2013-10-05 10:00:35

标签: .net

以下代码用于从.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

0 个答案:

没有答案