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
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;
User contributions licensed under CC BY-SA 3.0