I have a BackgroundWorker
that runs a job generating a large amount of text.
When it's complete, I need it to execute an Async/Await
Task
Method, which writes and colorizes the text in a RichTextBox
.
The Async/Await
Task
is to prevent the MainWindow
UI thread from freezing while work is being calculated, such as searching and colorizing, for the RichTextBox
.
Error
Exception: "The calling thread cannot access this object because a differnt thread owns it."
I get this error unless I put the Async/Await
code inside a Dispatcher.Invoke
.
But using a Dispatcher.Invoke
seems to negate the Async/Await
and cause the MainWindow
UI thread to freeze.
C#
public void Generate()
{
// Background Worker
//
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
BackgroundWorker b = o as BackgroundWorker;
// Generate some text
// ...
});
// When Background Worker Completes Job
//
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
// Write and Colorize text in RichTextBox
Task<int> task = Display();
bw.CancelAsync();
bw.Dispose();
});
bw.RunWorkerAsync();
}
// Method that Writes and Colorizes text in RichTextBox in MainWindow UI
//
public async Task<int> Display()
{
int count = 0;
await Task.Run(() =>
{
// Problem here, it will only work inside a Disptacher
//Dispatcher.Invoke(new Action(delegate {
// Write text
Paragraph paragraph = new Paragraph();
richTextBox1.Document = new FlowDocument(paragraph);
richTextBox1.BeginChange();
paragraph.Inlines.Add(new Run("Test"));
richTextBox1.EndChange();
// Colorize Text here...
// Is a loop that takes some time.
// MainWindow UI freezes until it's complete.
//}));
});
return count;
}