代码之家  ›  专栏  ›  技术社区  ›  RMD

多线程应用程序中的RichTextBox控件

  •  1
  • RMD  · 技术社区  · 15 年前

    我正在Windows服务中使用RichTextBox控件将RTF转换为纯文本。实际上,MS在这里提到了这种方法: http://msdn.microsoft.com/en-us/library/cc488002.aspx

    我的Windows服务产生多个线程(通常是CPU核心数的2倍),每个线程最后实例化RichTextBox控件的一个单独实例,并使用它将RTF转换为纯文本。

    这似乎工作得很好,但当服务运行在多核机器上时除外。(4+). 在这些场景中,服务偶尔会锁定。CPU以大约10%的速度旋转,什么也没发生。这将永远持续下去,除非你停止这个过程。我最终设法在调试过程中附加了一个调试器,结果证明这是RichTextBox控件正在做的事情。看起来像是在创建新窗口句柄时放置的内部锁。

    每次使用RichTextBox后,我都会将其处理掉。如果我强制服务使用更少的线程,这似乎不会发生,但这会显著降低我的服务在多核机器上的吞吐量。

    有人对如何解决这个问题有什么想法,或者有没有更好的方法将RTF转换为纯文本的想法?

    以下是其中一个被卡住线程的堆栈跟踪的相关部分:

      [In a sleep, wait, or join] 
    > System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams cp) Line 702 + 0x24 bytes C#
      System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() Line 5632 C#
      System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.CreateHandle() Line 1478 C#
      System.Windows.Forms.dll!System.Windows.Forms.RichTextBox.Rtf.set(string value) Line 759 C#
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   MCattle    11 年前

    这个问题的解决方法是使用richtextbox控件的线程静态实例。比如:

    [ThreadStatic]
    static RichTextBox m_RtfConverter;
    public static RichTextBox ThreadSafeRTFConverter {
        get {
            if(m_RtfConverter == null) {
                m_RtfConverter = new RichTextBox();
                m_RtfConverter.Width = 760;
            }
            return m_RtfConverter;
        }
    }
    
        2
  •  2
  •   Community CDub    8 年前

    检查此线程以获取正则表达式示例: Regular Expression for extracting text from an RTF string .

    可能有一些开源库用于将Rtf转换为纯文本(例如, http://sourceforge.net/projects/nrtftree/