C# program crashes when adding a Paragraph from another thread to a RichTextBox

0

I am trying to add a Paragraph to a RichTextBox control from another thread and my app crashes as soon as I try to do that

.Net Core 3.1

This is my Extensions source

public static class ParagraphExtention
    {
        public static void Append(this Paragraph paragraph, string value = "", Brush background = null, Brush foreground = null, bool bold = false, bool italic = false, bool underline = false, bool waitUntilReturn = false)
        {
            Action append = () =>
            {
                Inline run = new Run(value);

                if (background != null) run.Background = background;
                if (foreground != null) run.Foreground = foreground;
                if (bold) run = new Bold(run);
                if (italic) run = new Italic(run);
                if (underline) run = new Underline(run);

                paragraph.Inlines.Add(run);
            };
            if (paragraph.CheckAccess())
            {
                append();
            }
            else if (waitUntilReturn)
            {
                paragraph.Dispatcher.Invoke(append);
            }
            else
            {
                paragraph.Dispatcher.BeginInvoke(append);
            }
        }
    }

    public static class RichTextBoxExtensions
    {
        public static void CheckAppendText(this RichTextBox richtextBox, Paragraph msg, bool waitUntilReturn = false)
        {
            //Action append = () =>
            Action append = () =>
            {
                richtextBox.Document.CheckAppendText(msg);
            };
            if (richtextBox.CheckAccess())
            {
                append();
            }
            else if (waitUntilReturn)
            {
                richtextBox.Dispatcher.Invoke(append);
            }
            else
            {
                richtextBox.Dispatcher.BeginInvoke(append);
            }
        }
    }

    public static class FlowDocumentExtensions
    {
        public static void CheckAppendText(this FlowDocument fDoc, Paragraph msg, bool waitUntilReturn = false)
        {
            //Action append = () =>
            Action append = () =>
            {
                //Paragraph msgx = msg;
                // msgx.Inlines.Add(Environment.NewLine);

                fDoc.Blocks.Add(msg);
            };
            if (fDoc.CheckAccess())
            {
                append();
            }
            else if (waitUntilReturn)
            {
                fDoc.Dispatcher.Invoke(append);
            }
            else
            {
                fDoc.Dispatcher.BeginInvoke(append);
            }
        }
    }

Which is how I add a Paragraph but no idea why its not working

Also this is the error I am getting

MS.Internal.PtsHost.UnsafeNativeMethods.PTS.SecondaryException
  HResult=0x80131500
  Message=The calling thread cannot access this object because a different thread owns it.
  Source=WindowsBase
  StackTrace:
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
   at System.Windows.Documents.Paragraph.get_KeepWithNext()
   at MS.Internal.Text.DynamicPropertyReader.GetKeepWithNext(DependencyObject element)
   at MS.Internal.PtsHost.BaseParagraph.GetParaProperties(FSPAP& fspap, Boolean ignoreElementProps)
   at MS.Internal.PtsHost.ContainerParagraph.GetParaProperties(FSPAP& fspap)
   at MS.Internal.PtsHost.PtsHost.GetParaProperties(IntPtr pfsclient, IntPtr nmp, FSPAP& fspap)

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: The calling thread cannot access this object because a different thread owns it.

There isn't anything else really and I just use the Extentions like this

Paragraph p1 = new Paragraph();
p1.Append("Hello", Brushes.Transparent, Brushes.Green, true, false, false);
iSAPPRemoteUI.richtextBox_console.CheckAppendText(p1);

All this use to be fine when i just used plain text all problem started to happen when i tried to add the formatting

c#
multithreading
richtextbox
asked on Stack Overflow Jul 23, 2020 by POQDavid • edited Jul 23, 2020 by POQDavid

1 Answer

0

The thread that created the control (likely the main thread i.e. the main user interface thread) has ownership of the control. Other threads cannot use this.

In order to help with this, you need to run any interactions in the same thread.

In wpf you can use the dispatcher for this. There are many resources online, e.g: https://stackoverflow.com/a/1644254/4122889

In winforms, you can actually use control.Invoke(..) for this, e.g.

if (lblDescription.InvokeRequired)
    {
        DispatchHandler handler = delegate()
            {
                lblDescription.Text = description;
            };
            this.BeginInvoke(handler);
    }
    else
       lblDescription.Text = description;

source

answered on Stack Overflow Jul 23, 2020 by sommmen

User contributions licensed under CC BY-SA 3.0