2009-09-29 6 views
1

J'utilise un contrôle RichTextBox dans un service Windows pour convertir RTF en texte brut. Cette méthode est actuellement mentionnée par MS ici: http://msdn.microsoft.com/en-us/library/cc488002.aspxContrôle RichTextBox dans une application multithread

Mon service Windows génère plusieurs threads (généralement 2 x le nombre de cœurs de processeur), et chacun de ces threads instancie une instance distincte du contrôle RichTextBox et l'utilise pour convertir RTF en texte brut.

Cela semble fonctionner, sauf lorsque le service est exécuté sur des machines avec plusieurs cœurs. (4+). Dans ces scénarios, le service est parfois bloqué. Le processeur tourne à environ 10%, et rien ne se passe. Cela continuera indéfiniment si vous ne tuez pas le processus. J'ai finalement réussi à attacher un débogueur pendant qu'il se produisait, et il s'avère que c'est quelque chose que le contrôle RichTextBox fait. Ressemble à un verrou interne placé lors de la création d'une nouvelle poignée de fenêtre.

Je m'assure que je dispose de la RichTextBox après chaque utilisation. Cela ne semble pas se produire si je force le service à utiliser moins de threads, mais cela réduit considérablement le débit de mon service sur les machines multi-core.

Quelqu'un at-il des idées sur la façon de résoudre ce problème, ou une idée sur une meilleure façon de convertir RTF en texte brut?

Voici la partie pertinente de la trace de la pile d'un des fils qui est coincé:

[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# 

Répondre

3

La résolution de ce problème consistait à utiliser une instance statique de thread du contrôle richtextbox. Quelque chose comme:

[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; 
    } 
} 
Questions connexes