Interface do usuário sem resposta quando dados muito rápidos e em excesso precisam ser atualizados

Fiz um controle para registrar mensagens de diferentes threads na tela. Ele usa a caixa de rich text para exibir o texto formatado.

Quando há 20 threads que anexam suas mensagens a cada 200-250ms, a interface do usuário principal deixa de responder por algum tempo e após o processamento das mensagens em espera, a interface do usuário começa a responder novamente. Quando os threads estão em execução, a movimentação da janela não é suav

A mensagem escrita na caixa de rich text é sincronizada com os bloqueio

O que você pode sugerir para melhorar o desempenho? Estou planejando executar 100 threads.

Aqui está o meu código. Redireciono a (s) saída (s) do console para ele e ele registra tudo o que está acontecendo e é exibido em formato formatado dentro de uma caixa de rich tex

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

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

Após o console ser redirecionado para todos os Console.WriteLine ("bla bla"); é gravado na tela.

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();
        }
    }
}

questionAnswers(3)

yourAnswerToTheQuestion