1

更新:重要な部分は、使用しているストリームが copyto\copytoasync で使用されるバッファーに対して大きすぎるため、タスク全体を非同期で実行するのではなく、以下にリンクされている質問のように、ストリームを部分的に非同期で処理する必要があることです。

ここでVB.netコードを許してください。私は C# も話せるので、どちらの言語でも気軽に回答してください。

ここの例に従っています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 は文字列ですが、バッファとオフセットも必要であるだけでなく、ここで何を提供すればよいかわかりません。

どんな提案も歓迎します、ありがとう!

4

2 に答える 2

1

を使用する代わりに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;
}
于 2012-11-30T15:09:28.543 に答える
0

MemoryStream だけでなく、 StreamWriterクラスの使用を検討することもできます。これにより、次のようなことができます。

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

...[snip]...

outputWriter.Write(e.Data);
于 2012-11-30T15:11:11.993 に答える