UI que no responde cuando es demasiado rápido y se deben actualizar demasiados datos

Hice un control para registrar mensajes de diferentes hilos en la pantalla. Utiliza un cuadro de texto enriquecido para mostrar texto formateado.

Cuando hay 20 hilos que añaden sus mensajes cada 200-250 ms, la interfaz de usuario principal deja de responder por un tiempo y después de que se procesan los mensajes en espera, la interfaz de usuario comienza a responder nuevamente. Cuando los hilos se están ejecutando, el movimiento de la ventana no es uniforme.

La escritura de mensajes en el cuadro de texto enriquecido se sincroniza con bloqueos.

¿Qué puede sugerir para mejorar el rendimiento? Estoy planeando ejecutar 100 hilos.

Aquí está mi código. Redirecciono la (s) salida (s) de la consola y registra todo lo que está sucediendo y se muestra en forma formateada dentro de un cuadro de texto enriquecido.

public void RedirectStandardOutput()
        {
            Console.SetOut(ConsoleStream);

            System.Diagnostics.Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Debug.AutoFlush = true;
        }

Después de que la consola se redirige, Console.WriteLine ("bla bla"); está escrito en la pantalla.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CoreLib.Parsers;

namespace ConsoleWidget
{
    public class ConsoleStream : System.IO.TextWriter
    {
        private readonly object _textBoxLock = new object();

        public RichTextBox TextBox { get; set; }
        public List<TextFormat> TextFormatList { get; set; }

        public bool AutoClear { get; set; }
        public int AutoClearLength { get; set; }
        public bool AutoSave { get; set; }
        public string AutoSaveDir { get; set; }


        public ConsoleStream()
        {
            TextFormatList = new List<TextFormat>();
        }

        public void AppendText(string text)
        {
            if (TextBox == null) return;

            var textLength = TextBox.TextLength;

            if (AutoClear && textLength > AutoClearLength)
            {
                if (AutoSave)
                {
                    var dir = string.Format(@"{0}\{1}\{2}", Environment.CurrentDirectory, AutoSaveDir, CoreLib.Extensions.DateTimeExtensions.DateTimeNowDir);

                    if (!System.IO.Directory.Exists(dir))
                        System.IO.Directory.CreateDirectory(dir);

                    var path = string.Format(@"{0}\{1}.log", dir, CoreLib.Extensions.DateTimeExtensions.GetDateTimeNowFileName);

                    TextBox.SaveFile(path);
                }

                TextBox.Clear();
            }

            TextBox.AppendText(text);

            // Format text.
            foreach (var textFormat in TextFormatList)
            {
                int beginIndex;
                int length;

                if (textFormat.GetFormatProperties(text, out beginIndex, out length))
                {
                    // RichTextBox counts newline "\r\n" which is double char as single char.
                    // Causes shifting in selection starts. The lines below count the "\r" chars before the beginIndex.
                    var leftText = text.Substring(0, beginIndex);
                    var newLineCount = leftText.Count(c => c == '\r');

                    TextBox.SelectionStart = textLength + beginIndex - newLineCount;
                    TextBox.SelectionLength = length;
                    if (!textFormat.Color.IsEmpty)
                        TextBox.SelectionColor = textFormat.Color;
                    if (textFormat.Font != null)
                        TextBox.SelectionFont = textFormat.Font;
                }
            }

            TextBox.ScrollToCaret();
        }

        public void Clear()
        {
            lock (_textBoxLock)
            {
                TextBox.Clear();
            }
        }

        public int TextLength
        {
            get
            {
                lock (_textBoxLock)
                {
                    return TextBox.TextLength;
                }
            }
        }

        public void SaveAs(string path)
        {
            lock (_textBoxLock)
            {
                TextBox.SaveFile(path);
            }
        }

        public override Encoding Encoding
        {
            get { return Encoding.Default; }
        }

        public override void Write(string value)
        {
            if (TextBox == null) return;

            var action = (Action)(() => AppendText(value));

            lock (_textBoxLock)
            {
                if (TextBox.InvokeRequired)
                    TextBox.BeginInvoke(action);
                else
                    action();
            }
        }

        public override void WriteLine()
        {
            Write(NewLine);
        }

        public override void WriteLine(string value)
        {
            Write(value);
            WriteLine();
        }
    }
}

Respuestas a la pregunta(3)

Su respuesta a la pregunta