.net - 将进程从进程输出异步读取到内存流

  显示原文与译文双语对照的内容
0 0

注意:我们正在使用的数据流太大,因为我们正在使用的缓冲区太大,所以我们需要异步处理数据流,如下面的问题

请原谅这里的VB.Net 代码。 我也会说 C#,因这里可以随意使用 repsond 。

我一直在遵循这里的例子 ProcessStartInfo挂在"waitforexit"上? 为什么为了尝试解决一个问题,我们已经用光了缓冲区空间?

以前,我们尝试使用以下代码:


 Dim buffer As Byte() = New Byte(32767) {}
 Dim file As Byte()
 Using ms = New MemoryStream()
 While True
 Dim read As Integer = Process.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length)

 If read <= 0 Then
 Exit While
 End If
 ms.Write(buffer, 0, read)
 End While
 file = ms.ToArray()
 End Using

 If Not Process.WaitForExit(timeOut) Then
 Throw New Exception("Html to PDF conversion timed out.")
 End If

现在我已经开始从链接问题转换为aynch方法,但是写入内存流而不是 StringBuilder 。 这是我目前所拥有的:


Dim output = new MemoryStream()
Dim errorOutput = new StringBuilder()

Using process = New Process()

 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.Write(e.Data);//compile error here
 End If

 End Function

 End Using
 End Using

End Using

当然 e.Data 是一个字符串,但我不仅需要一个缓冲区和一个偏移量。 不确定该在这里提供什么。

欢迎你的建议,谢谢 !

时间: 原作者:

0 0

你可以直接使用流,而不用使用 OutputDataReceived:


static async Task<MemoryStream> ReadProcessOutput(ProcessStartInfo psi)
{
 MemoryStream ms = new MemoryStream();

 using (Process p = new Process())
 {
 p.StartInfo = psi;

 TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
 EventHandler eh = (s, e) => tcs.TrySetResult(0);

 p.Exited += eh;

 try
 {
 p.EnableRaisingEvents = true;
 p.Start();

 await p.StandardError.BaseStream.CopyToAsync(ms);
 await tcs.Task;
 }
 finally
 {
 p.Exited -= eh;
 }
 }

 return ms;
}

原作者:
0 0

你可能希望使用 StreamWriter 类,而不是仅查看 MemoryStream 。 这将允许你执行如下操作:


MemoryStream output = new MemoryStream();
StreamWriter outputWriter = new StreamWriter(output);

...[snip]...

outputWriter.Write(e.Data);

...