【发布时间】:2013-01-11 21:12:29
【问题描述】:
我有一个相当标准的设置:
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 或 TextWriter 的同步方法。这也适用 到 StreamWriter 和 StreamReader 等类。在 System.Buffer.InternalBlockCopy(Array src, Int32 srcOffset, Array dst, Int 32 dstOffset,Int32 计数)在 System.IO.StreamWriter.Write(Char[] 缓冲区,Int32 索引,Int32 计数) 在 System.IO.TextWriter.WriteLine(字符串值)
我只在我的应用程序中运行一个线程,所以我认为发生这种情况的唯一方法是如果 stdout 和 stderror 同时触发事件。
实现上述“线程安全包装器”的代码应该是什么样的?
【问题讨论】:
-
您可能应该编辑您的问题并制作一个简短但完整的程序,以便不太高级的用户在遇到问题时也能理解。
-
哇,很棒的异常消息。