ここで説明したように、ProcessStartInfoは「WaitForExit」にぶら下がっていますか?なんで?-大きな出力でp.WaitForExit()を呼び出すと、OutputStreamがいっぱいになり、プロセスと出力ストリームが相互に待機するときにデッドロックが発生します。
たとえば私のコード:
Dim p = New Process()
Dim ReturnValue As Boolean = False
p.StartInfo = New ProcessStartInfo(LynxPath, "-dump -nolist -width 1000 " & HtmlBuffer)
p.StartInfo.WorkingDirectory = WorkingRoot
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
p.StartInfo.CreateNoWindow = True
p.Start()
ReturnValue = p.WaitForExit(5000)
LYNXからの大きな出力を処理する場合、上記のようにタイムアウトを使用しない限り、スレッドがハングし、出力バッファーがいっぱいになると出力がトリミングされます。つまり、読み取った出力が完了していません。
上記の質問に投稿されたc#ソリューションは OutputDataReceived
、プロセスクラスのイベントを利用することでこれを回避しているようです。しかし、私の問題は、そのc#コードをvb.net 3.5に変換することです。通常の変換ルートを実行すると、次のように出力されます。
Using process As New Process()
process.StartInfo.FileName = filename
process.StartInfo.Arguments = arguments
process.StartInfo.UseShellExecute = False
process.StartInfo.RedirectStandardOutput = True
process.StartInfo.RedirectStandardError = True
Dim output As New StringBuilder()
Dim [error] As New StringBuilder()
Using outputWaitHandle As New AutoResetEvent(False)
Using errorWaitHandle As New AutoResetEvent(False)
process.OutputDataReceived += Function(sender, e)
If e.Data Is Nothing Then
outputWaitHandle.[Set]()
Else
output.AppendLine(e.Data)
End If
End Function
process.ErrorDataReceived += Function(sender, e)
If e.Data Is Nothing Then
errorWaitHandle.[Set]()
Else
[error].AppendLine(e.Data)
End If
End Function
process.Start()
process.BeginOutputReadLine()
process.BeginErrorReadLine()
' Process completed. Check process.ExitCode here.
If process.WaitForExit(timeout) AndAlso outputWaitHandle.WaitOne(timeout) AndAlso errorWaitHandle.WaitOne(timeout) Then
' Timed out.
Else
End If
End Using
End Using
End Using
ただし、Visual Studio 2008は、関数のデクレレーションを無効な構文としてフラグを立てます(このようなインラインメソッドは4.5以降にあると思いますか?)。3.5でこの例をどのように利用するのでしょうか。
編集:ちょうどこのリンクを見つけました:http://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived.aspx-今それを理解しようとしています