【问题标题】:StringTemplate Probable I/O race condition detected while copying memoryStringTemplate 复制内存时检测到可能的 I/O 竞争条件
【发布时间】:2015-03-17 13:10:59
【问题描述】:

喂,

在我的项目中,我使用 Antlr.StringTemplate.StringTemplateGroup 类来创建本地化模板。我访问 .st 文件并设置所需的属性如下。

public StringTemplate WrapValuesReportTemplateContent(   
   private StringTemplateGroup StringTemplateGroup = new StringTemplateGroup(StringTemplateGroupName);     

   StringTemplate stringTemplate = this.StringTemplateGroup.GetInstanceOf(path);

   stringTemplate.SetAttribute("atr1", value1);
   stringTemplate.SetAttribute("atr2", value2);

   return stringTemplate
)

该类被经理重复使用,因此触发了以下异常。

    System.IndexOutOfRangeException: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithread applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.
   at System.Buffer.InternalBlockCopy(Array src, Int32 srcOffsetBytes, Array dst, Int32 dstOffsetBytes, Int32 byteCount)
   at System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count)
   at System.IO.TextWriter.WriteLine(String value)
   at System.IO.TextWriter.SyncTextWriter.WriteLine(String value)
   at Antlr.StringTemplate.ConsoleErrorListener.Error(String s, Exception e)
   at Antlr.StringTemplate.StringTemplate.BreakTemplateIntoChunks()

我对 StringTemplate 很陌生,我不清楚 StringTemplates 是如何工作的。从错误描述中我了解到 .st 资源没有关闭。我有以下问题:

  1. 在创建新的 StringTemplate 时,我们会创建一个 Stream 用于写入和读取 .st 文件,或者我们修改属性的新对象
  2. .st 文件打开后是否会在超出范围时自动关闭
  3. 为了避免此错误,最好的方法是什么。我们应该对资源使用锁,还是将所有内容都包装在 using 中?

任何澄清都会非常有用。 谢谢

【问题讨论】:

  • 您是否从多个线程访问模板?
  • 是的,它是一个多线程应用程序。
  • 你的问题有更详细的答案here

标签: race-condition stringtemplate


【解决方案1】:

您可以尝试同步对 stringTemplate 对象的访问。

我的猜测是,如果您同时修改它并读取或修改它,您将只需要同步。如果您只是阅读它,通常没关系。

    lock (stringTemplate)
    {
        // Access thread-sensitive resources.
    }

出于效率原因,您应该使同步块尽可能小;只需使用 stringTemplate 访问即可。

【讨论】:

  • 这是我不完全理解它是如何工作的问题。如果我创建一个新的 StringTemplate 并使用 addAttribute 属性,我正在将此属性写入 .st 文件,或者我只是在修改 StringTemplate 对象?我找不到任何关于它的明确文件。目前,每次我使用 StringTemplateGroup 实例时都会添加一个锁(新对象()){}。
  • 我不认为你写的锁码会做任何事情。你是从哪里弄来的?
  • 这是某人的建议。该对象未在锁内声明。但实际上我们创建一个对象只是为了设置一个锁。直到现在我才考虑在 stringTemplate 上设置锁。谢谢
【解决方案2】:

我最近遇到了同样的错误! 查看您的堆栈跟踪:它是从 ConsoleErrorListener 抛出的。 简而言之,抛出异常是因为两个线程试图写入 Console.Out 流。 要消除此错误,您应该覆盖模板的错误处理程序。

标记为答案的解决方案会起作用,但会出现过多的锁争用。

【讨论】:

    猜你喜欢
    • 2019-04-26
    • 1970-01-01
    • 2013-04-13
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 2019-09-09
    • 1970-01-01
    相关资源
    最近更新 更多