2015-05-14 6 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() или поместил его в блок using в C# вместо вызова proc.kill(), что должно быть сделано после WaitForExit().

Проверьте мой ответ на Opening a DOS Console.

Также проверьте this reply, говоря, что если вы перенаправляете как stdOut, так и stdErr, вы должны сделать хотя бы один асинхронный.

+0

Большое спасибо, я не думаю, что использую Process.Read()? В любом случае, как чтение stdout, так и stderr являются асинхронными? Вы уверены, что kill() следует делать после waitforexit, а не наоборот? [NB: Блок использования вызовет Dispose после того, как proc покинет область. Я подозреваю, что я, вероятно, не должен вызывать Dispose, пока процесс все еще запущен?] –

+0

Я принял этот ответ как любезность. См. Мой ответ на комментарий Хассанта, если у вас такая же проблема. –

+0

Спасибо @Joe, но если вы нашли ответ на свой вопрос, вы должны отправить ответ самостоятельно. Через день или около того вы можете принять свой собственный ответ. Это поможет другим людям. –

Смежные вопросы