1
votes

Whats the best way to run a function that syntax highlights text in a text box (left of = is red, right of = is blue). I ask because I had the data retrival in a CommandTask thread, and then did the highlighting in the FinishCommand (in UI thread) and that seemed to work but would deadlock the UI for a bit while it chugged away highlighting.

So, then I tried placing the highlighting code in a specalized RichTextBox Invoke function (thus thread safe) and moved the function call in the thread. That also worked, but for some reason was consistantly 4-8 seconds slower; this makes no sense to me because its the exact same code.

Finally, I tried making a temp RichTextBox in the thread, pasting the resulting text to it and highlighting. Then, all the Invoke function did was pass along the RTF to the real RichTextBox, but in this case for some reason the RTF isn't quite right, its the color gets shifted by 2 each time Ex: R=red, B=Blue, X=Black chars

Line 1. RRRRXBBBB (correct)

Line 2. XXRRRRBBB (coloring shifted 2 to the right)

Line 3. XXXXRRRRX (shifted 4 to the right, and so on)

So, my overarching question is which approach is best, why is threading the exact same code slower, and if approach 3 is the best, whats up with that wierd color shifting. Thanks!

2

2 Answers

3
votes

It is slower because invoking is expensive. It requires two thread context switches and the UI thread has to be idle. Do this for every single highlighting change and you'll seriously bog down the thread. Using BeginInvoke() would fix that, but now you'll bog down the UI thread so it gets unresponsive. In other words, you can't win with that strategy.

Not sure what's going wrong with the helper RTB. It is off by two for each line, smells like a simple bug. Like not accounting for a carriage return + line feed at the end of the line.

A better way to speed this up is to tell the RTB to not update itself when you're busy highlighting text. Very big difference. That's not built-in but you can easily add it. And consider cutting your losses, RTB is just not a very good editor. Look at ScintillaNET.

0
votes

A typical approach is to implement some kind of RTF generator that builds an RTF-compatible string using fast string manipulation (StringBuilder, StringWriter, etc), and then replace the RichTextBox control's RTF code with your own:

string rtf = /* Generate RTF code based on original text */
richTextBox.Rtf = rtf; // Replace text box's RTF code

You can find documentation on the RTF format here:

http://msdn.microsoft.com/en-us/library/aa140277%28v=office.10%29.aspx

You'll basically need to generate:

  • RTF Header
  • Font Table
  • Color Table
  • Character Text

You can do this through trial-and-error by using Wordpad, create a simple document with the syntax highlighting you desire, save the document in RTF format, and then open it in Notepad or similar application and then analyze the RTF generated.

Benefit of this method is that you can generate the RTF code in a separate thread and then update the user interface only once when the code is generated.