I recently converted my application from WinForms to WPF, and I'm happy with most of the new features. However, there is a major stumbling block I've hit. When I append text constantly to my textboxes, the UI thread becomes so blocked up that I can't do anything but watch it append text! I need to be able to switch tabs in my tab control, click buttons, etc etc. The strange thing is that I have absolutely no slowdown in the UI thread in WinForms!
So, here's a little background on my application: it runs other processes as part of an "action queue", and spits out those process's stdout and stderr into two separate textboxes, as well as the log textbox (these are the impacted textboxes). On low output processes, there is no slowdown, but when I use processes like SVN checkout and file copying, I get so much text output at once that all it can do is append text.
Here's my code for printing:
public void PrintOutput(String s)
{
String text = s + Environment.NewLine;
Window.Dispatcher.Invoke(new StringArgDelegate(Window.PrintOutput), text);
Debug.Log("d " + text);
}
public void PrintLog(String s)
{
ClearLogButtonEnabled = true;
String text = s + Environment.NewLine;
Window.Dispatcher.Invoke(new StringArgDelegate(Window.PrintLog), text);
}
and the matching code-behind:
public void PrintOutput(String s)
{
outputTextBox.AppendText(s);
outputTextBox.ScrollToEnd();
if (!clearOutputButton.IsEnabled) clearOutputButton.IsEnabled = true;
}
public void PrintLog(String s)
{
logTextBox.AppendText(s);
logTextBox.ScrollToEnd();
}
Just so that I don't get a bunch of accusations saying that I'm doing my work on the UI thread as well, here is my code for starting up the separate worker thread:
Thread actionThread = new Thread(new ThreadStart(ActionManager.Instance().ExecuteActions));
actionThread.Name = "Action Manager Work Thread";
actionThread.Start();
This is the thread that handles starting, running, and cleaning up of all the auxiliary processes. These processes use the print methods shown above to print their stdout/stderr output. Additionally, each process gets its own thread!
Thread procThread = new Thread(new ThreadStart(StartProcess));
procThread.Name = action.Name + "_" + Guid.NewGuid();
procThread.Start();
My worry is that WPF is slower at Invokes in some way and that I'm screwed. I put a lot of work into switching this application to WPF from WinForms, so if anyone knows why I'd be getting such a massive slowdown in print speeds please let me know!
EDIT:
I should also add that I am using a RichTextBox
, not a TextBox
, and that I need the features of the RichTextBox
to bold certain text. If there is a way to provide bold text with a less cumbersome TextBox class please let me know.