Adding a child to Viewport3D asynchronously gives “This API was accessed with arguments from the wrong context.”

StackOverflow https://stackoverflow.com/questions/1808417

Question

When I try to add 3D-content to a Viewport3D, asynchronously, this results in "This API was accessed with arguments from the wrong context." in a TargetInvocationException.

The 3D-content is generated from the data of a 3D-scanning device. The communication&calculations needed for that are done in a separate thread. First, I tried to acces the viewport3D from that thread. I realized this should be done by the GUI-thread, so now I use this code:

        ModelVisual3D model = new ModelVisual3D();
        model.Content = scanline;

        DispatcherOperation dispOp = this.viewport.Dispatcher.BeginInvoke(
            new AddModelDelegate(StartAddModel), model);
    }
    private void StartAddModel(ModelVisual3D model)
    {
        this.viewport.Children.Add(model); 
        //model is not in the context of this current thread. 
        //Throws exception: "This API was accessed with arguments from the wrong context."
    }

    private delegate void AddModelDelegate(ModelVisual3D model);

It seems that the object named "model" is not in the context of the current thread. How can I fix this? Is there a way to get the model to the context of the Dispatcher? Or is this way of doing this just not the way to go here?

Was it helpful?

Solution

This will occur when ever you generate/modify scene objects to add to Viewport, from a different thread then the one Viewport was instantiated on. There is a simple work around. Encapsulate the code that updates Viewport objects into a function. Insert the following snippet and you are done.

private delegate void MyFunctionDelegate();
void MyFunction()
{
     if(!Application.Current.Dispatcher.CheckAccess())
     {
         Application.Current.Dispatcher.Invoke(new MyFunctionDelegate(MyFunction));
         return; // Important to leave the culprit thread
     }
     .
     .
     .
     this.Viewport3D.Children.Remove(model);
     MyModifyModel(model);
     this.Viewport3D.Children.Add(model); 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top