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

时间:2009-09-29 20:49:06

标签: c# winforms multithreading richtextbox

我在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 个答案:

答案 0 :(得分:3)

解决此问题的方法是使用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;
    }
}

答案 1 :(得分:2)

检查此主题是否为正则表达式示例:Regular Expression for extracting text from an RTF string

可能有一些开源库用于将Rtf转换为纯文本(例如,http://sourceforge.net/projects/nrtftree/ - 尚未对其进行测试,但看起来您可能很容易为每个Rtf节点提取文本。)

在非gui线程中实例化控件听起来很麻烦。