0
votes

I'm currently wondering how I can avoid this error from this snippet of code contained inside of a loop.

var seriesColour = new LinearGradientBrush();
JSColor color = null;

seriesColour.Dispatcher.Invoke((System.Action)(() =>
{
    seriesColour = _colourBrushes[field.SeriesColour];
    color = new JSColor()
    {
        linearGradient = new JSGradient()
        {
            x1 = (int)seriesColour.StartPoint.X,
            y1 = (int)seriesColour.StartPoint.Y,
            x2 = (int)seriesColour.EndPoint.X,
            y2 = (int)seriesColour.EndPoint.Y
        },
        stops = new object[]
        {
            new object[] { seriesColour.GradientStops[0].Offset,  RGBConvert(seriesColour.GradientStops[0]) },
            new object[] { seriesColour.GradientStops[1].Offset, RGBConvert(seriesColour.GradientStops[1]) }
        }
    };
}));

I seem to get the error in the title, whenever I refresh the page (run it the second time around). Anybody any ideas?

2
Hmm, no, that sure looks borken. High odds that the brush is getting created on the wrong thread and its dispatcher doesn't actually invoke to the UI thread. Use Application.Current.Dispatcher to get ahead. - Hans Passant

2 Answers

2
votes

The idea behind using a Dispatcher to have the SAME thread operating on everything. Because you created seriesColour on lets say ThreadA, then when you call it's Dispathcer.Invoke(), its just calling it on ThreadA.

So, if one of the other components you are referencing was created on ThreadB, then you're going to have a problem.

So as @HansPassant suggested, try Application.Current.Dispatcher.Invoke(). However, I would think you would also want to create seriesColour within the Invoke() as well.

1
votes

This is a problem that usually happens when you're trying to update your UI components from a thread other than the main thread.

The reason of your problem seems like that the seriesColour component is being created in a different thread (different from the UI thread) and maybe its Dispatcher object isn't invoking the UI thread (and you have a multithreading issue while trying to update something in the UI).

Use seriesColour.Dispatcher.CheckAccess() to check whether the current thread owns the seriesColour component. If it owns it, everything is okay. Otherwise, do the work in the UI using:

this.Dispatcher.Invoke((Action)(() =>
{
        seriesColour = _colourBrushes[field.SeriesColour];
        ...// your code here.
}));