So my application does as follows:
Main Thread:
Both properties are created in the main thread, and it's only the AxisAngleRotation3D.Angle, Axis and InternalQuaternion that give the error. Debugging, I can confirm that the AxisAngleRotation3D object is created in the MainThread, and can't find any place on my code where it's accessed again, I've commented the only line where it's changed, so the only thing it does is be instantiated.
I'm totally lost here. Shouldn't I be able to access objects created in the parent thread? It works for other threads that I create similarly.
Is there any way I can see which thread owns the object that is throwing the exception, or debug when the AxisAngleRotation3D properties are being changed outside my own code?
I open the threads with ThreadPool.QueueUserWorkItem
Thanks
The problem looks like it's already stated:
The bottom line is that if you need cross thread access to UI objects you have a couple options:
Freezable
and you aren't going to change it's values you can freeze it. (Vectors and Rotations are Freezable)Freezing Objects
if(freezable.CanFreeze)
{
freezable.Freeze();
}
At this point you can read the objects on any thread--but you can't edit them again. You can get an unfrozen copy of the class by calling the Clone()
method and manipulate that, but you can't change values on the frozen object.
Using the Dispatcher
Freezable objects are also DependencyObjects
so this works for anything in the UI layer:
var myAngle = myRotation.Dispatcher.CheckAccess()
? myRotation.Orientation.Angle
: (double)myRotation.Dispatcher.Invoke(() => myRotation.Orientation.Angle);
Of course, if the thread you are on is the UI thread (Dispatcher.CheckAccess() == true
) then you don't need to worry about accessing the property. If it is any other thread (Dispatcher.CheckAccess() == false
), then you have to pause this thread, queue work on the dispatcher and return when it is done.