无法访问主线程上的对象

Can't access object on main thread

所以我的应用程序如下:

主线程:

  1. 创建新对象 1,它在其构造函数中启动 Thread1。
  2. 实例化 object2,它包含一个 Vector3D 和一个 AxisAngleRotation3D(除其他外)
  3. 做事
  4. Thread1 尝试访问 object2.Position (Vector3D) 和 object2.Orientation (AxisAngleRotation3D)。位置没问题,Orientation.Angle 抛出 'System.InvalidOperationException' 说 "Calling thread cannot access the object because another thread owns it"。

这两个属性都是在主线程中创建的,只有 AxisAngleRotation3D.Angle、Axis 和 InternalQuaternion 会出错。调试,我可以确认 AxisAngleRotation3D 对象是在 MainThread 中创建的,并且在我的代码中找不到任何再次访问它的地方,我已经注释了它唯一更改的行,所以它唯一做的就是实例化.

我完全迷失在这里。我不应该能够访问在父线程中创建的对象吗?它适用于我以类似方式创建的其他线程。

有什么方法可以查看哪个线程拥有引发异常的对象,或者在我自己的代码之外更改 AxisAngleRotation3D 属性时进行调试?

我用 ThreadPool.QueueUserWorkItem

打开线程

谢谢

问题好像已经说明了:

  • 在主线程(线程 0)上创建的对象
  • 试图从线程 1 访问对象:抛出 InvalidOperationException

底线是,如果您需要跨线程访问 UI 对象,您有几个选择:

  • 如果对象是 Freezable 并且您不打算更改它的值,则可以将其冻结。 (向量和旋转是可冻结的)
  • 否则,您可以使用依赖对象的调度程序来访问值

冻结对象

if(freezable.CanFreeze)
{
    freezable.Freeze();
}

此时您可以在任何线程上读取对象--但不能再次编辑它们。您可以通过调用 Clone() 方法并对其进行操作来获取 class 的未冻结副本,但您不能更改已冻结对象的值。

使用调度程序

Freezable 对象也是 DependencyObjects 所以这适用于 UI 层中的任何对象:

var myAngle = myRotation.Dispatcher.CheckAccess() 
    ? myRotation.Orientation.Angle
    : (double)myRotation.Dispatcher.Invoke(() => myRotation.Orientation.Angle);

当然,如果你所在的线程是UI线程(Dispatcher.CheckAccess() == true)那么你就不用担心访问属性。如果它是任何其他线程 (Dispatcher.CheckAccess() == false),那么您必须暂停该线程,在调度程序上排队工作,并在完成后 return。