1

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?

Bob Goblin
  • 1,251
  • 3
  • 16
  • 33
Tommehh
  • 872
  • 1
  • 17
  • 44
  • You error could be similar to this one:http://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it – Paul Karam Sep 08 '16 at 11:30
  • Possible duplicate of [List shared between different threads in .NET](http://stackoverflow.com/questions/4011031/list-shared-between-different-threads-in-net) – Imran Sh Sep 08 '16 at 11:30
  • as you can see, i already have implemented a Dispatcher.Invoke call – Tommehh Sep 08 '16 at 11:40
  • I think, the root issue is that you create a `Syntax` object in non-UI thread. I don't see any reason to use `Dispatcher.BeginInvoke` here, because after `await` you are already on the UI thread – just.ru Sep 08 '16 at 11:57

1 Answers1

1

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.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810