2015-05-14 230 views
1

以下代碼在最後對WaitForExit的調用中掛起。如果我消除1秒長的睡眠,它會乾淨地終止。有人可以告訴我該怎麼做,這個過程會在我打電話給Kill()之後不久就死掉了嗎?非常感謝。Process.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 
+1

當然,該過程實際上終止,使用任務管理器來驗證。 WaitForExit()不只是等待進程終止,它還會等到所有重定向輸出被讀取。爲什麼沒有發生這種事情很難猜到,除了Cygwin非常古怪。將Kill()調用移過取消調用可能會有所幫助。 –

+0

我發現你是正確的第一部分 - 非常感謝。我認爲問題在於,如果進程已經死了,WaitForExit不會終止(這直接違背了M $文檔,特別說明在kill()後調用它)。因此,只要流程處於活動狀態,修復只是提供超時和重試。順便說一句,取消的順序似乎沒有什麼差別。 –

回答

0

我不知道F#,但是這段代碼有幾個很奇怪的東西; Process.Read()是一個阻塞呼叫,因此您必須讓它們異步,否則請致電.ReadToEnd(),而不是等待重定向完成。我會使用proc.Dispose()或將它放在C#中的using塊中,而不是調用proc.kill(),這應在WaitForExit()之後完成。我的回答是Opening a DOS Console

也檢查出this reply說如果你重定向stdOut和stdErr,你必須至少有一個異步。

+0

非常感謝,我不認爲我使用Process.Read()?在任何情況下,stdout和stderr都是異步的?你確定kill()應該在waitforexit之後完成,而不是相反嗎? [注意:一旦proc離開範圍,use塊將調用Dispose。我懷疑我可能不應該在過程仍在運行時調用Dispose?] –

+0

我已接受此答案作爲禮貌。如果您有同樣的問題,請參閱我對H Passant的評論的回覆。 –

+0

謝謝@Joe,但如果您發現自己的問題的答案,您應該自己發佈答案。過了一天左右,你可以接受你自己的答案。這將有助於其他人。 –