私はかなり標準的な設定をしています:
void Run()
{
this.sw = File.CreateText(logfile)
start.RedirectStandardInput = true;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.UseShellExecute = false;
Process proc = Process.Start(start)
proc.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
proc.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
...
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
sw.WriteLine(outLine.Data);
}
}
最初の試運転を行い、数分後に完全に実行した後、クラッシュするまで、すべてがうまく機能していると思いました。
未処理の例外: 未処理の例外: System.IndexOutOfRangeException: メモリのコピー中に I/O 競合状態が検出された可能性があります。デフォルトでは、I/O パッケージはスレッドセーフではありません。マルチスレッド アプリケーションでは、TextReader または T xtWriter の Synchronized メソッドによって返されるスレッド セーフなラッパーなど、スレッド セーフな方法でストリームにアクセスする必要があります。これは、StreamWriter や StreamReader などのクラスにも当てはまります。System.Buffer.InternalBlockCopy (配列 src、Int32 srcOffset、配列 dst、Int 32 dstOffset、Int32 カウント) で System.IO.StreamWriter.Write (Char[] バッファー、Int32 インデックス、Int32 カウント) で System.IO.TextWriter。 WriteLine(文字列値)
私は自分のアプリで単一のスレッドしか実行していないので、これが起こったと考えることができる唯一の方法は、stdout と stderror の両方が同時にイベントを発生させる場合です。
言及された「スレッドセーフラッパー」を実装するには、コードはどのように見えるべきですか?