Tommehh
Tommehh

Reputation: 946

Accessing Object from different thread - Tasks

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

Answers (1)

Stephen Cleary
Stephen Cleary

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

Related Questions