Reputation: 946
i am new to tasks and don't really know if its good to use it the way i want.
I have a Class which inherits from TextBlock and colorize the text (Syntaxhighlighting). It does take awhile so i want to do it in Background
Here is my code so far:
async void SyntaxTextBlock_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
{
if ((clientSettings.SyntaxCheck || clientSettings.SyntaxHighlighting) && !string.IsNullOrEmpty(Text))
{
string value = Text;
Syntax syntax = await Task.Factory.StartNew(() => DoSyntax(value));
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
if (syntax.IsTextDecoration)
TextDecorations.Add(Syntax.TextDecoration);
ToolTip = string.Join(Environment.NewLine, syntax.Messages);
Text = null;
foreach (Run run in syntax.Runs)
Inlines.Add(run);
}));
}
}
My problem is i cant access the syntax.Runs
List from the object Syntax
which is returned by DoSyntax(value)
.
Error: the calling thread cannot access this object because a different thread owns it
I tried it with the scheduler TaskScheduler.FromCurrentSynchronizationContext
and it worked, but the GUI freezed.
Is there a way to do this on multiple different threads while the gui does not freeze?
Upvotes: 1
Views: 280
Reputation: 456322
The problem is that DoSyntax
is creating thread-affine objects (specifically, Syntax
) while on a background thread.
You'll need to change DoSyntax
so that it will only create "normal" objects (like a list of ranges with colors/semantics) on the background thread, and then have your UI thread process that and create the actual Syntax
types, if necessary.
Upvotes: 1