C# – Richtextbox.invoke, C#, Form Still hanging


I've written a c# application to run an external program and i've redirectet it's output to a richtextbox in my form. I've created the process using the following settings

p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);

and in the outputreceived event

void outputreceived(object sender, DataReceivedEventArgs e)
  if (!string.IsNullOrEmpty(e.Data))
    richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput),
                        new object[] { e.Data });

void updateoutput(string text)
  int len = text.Length;
  int start = richTextBox1.Text.Length;
  richTextBox1.Text += text + Environment.NewLine;
  richTextBox1.Select(start, len);
  richTextBox1.SelectionColor = System.Drawing.Color.White;
  richTextBox1.Select(richTextBox1.Text.Length, 0);

Now the thing is though it is working, but my main form which contains the textbox, hangs if the output is huge from the application. I think each time the invoke call leads to repainting of the form, which happens very frequently. Is there any alternative so that i can see the updates to the textbox as they happen and also keep the form completely active?


I think I got my answer, I used BeginInvoke when I should have used Invoke.

Update 1:

I tried both BeginInvoke and Suspendlayout but it is not giving me the desired functionality, what happens is that the process has returened all the standardoutput to the string, but the thread which is responsible for updating the text is taking it's own time to print the data. Can i do any thing to it?

Best Solution

Since you've already solved your problem, I'll just note that it will be faster if you use rtb.AppendText (instead of Text += ...) and use pinvoke to scroll to the bottom:

private const int WM_VSCROLL = 0x115;
private const int SB_BOTTOM = 7;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam,
IntPtr lParam);

// ...
// Scroll to the bottom, but don't move the caret position.
SendMessage(rtb.Handle, WM_VSCROLL, (IntPtr) SB_BOTTOM, IntPtr.Zero);
Related Question