0

语言:c# (wpf)

情况:我必须从文件中加载 3D 网格,然后填充 Viewport3D。

我想做什么:我想在 BackgroundWorker 中加载 3D 网格,因此应用程序在加载 3D 网格时不需要停止;这需要几秒钟。

问题:问题不在于如何使用 BackgroundWorker。这是有据可查的。当我想填充 Viewport3D 的 Model3DGroup(3D 对象组)时,就会出现问题。

从文件中加载 3D 网格时,在后台工作人员中,我使用网格中每个对象的所有点和三角形索引填充了一个自定义网格类。我将它们分别存储在 Point3DCollections 和 Int32Collections 中。

public class LFSMeshObject
{
    public Point3D Center;
    public int Radius;
    public int NumPoints;
    public int NumTris;

    public Color ObjectColor { get; private set; }
    public Point3DCollection Points { get; private set; }
    public Int32Collection Tris { get; private set; }

当这个填充对象被传回 GUI 线程时,我可以很好地读取存储在对象中的所有值和属性。我还可以读取我复制到 MeshGeometry3D 中的 Point3Dcollections 和 Int32Collections 进入 Model3DGroup,但随后得到线程所有者异常,因为后台填充对象的属性属于后台线程。

    DiffuseMaterial mDMat;
    MeshGeometry3D mGeom;
    Debug.WriteLine("num objects in mesh : {0}", _trackMesh.NumObjects);
    for (int a = 0; a < _trackMesh.NumObjects; a++)
    {
        mGeom = new MeshGeometry3D();
        mGeom.Positions = _trackMesh.TrackMeshObjects[a].Points;
        mGeom.TriangleIndices = _trackMesh.TrackMeshObjects[a].Tris;

        mDMat = new DiffuseMaterial();
        mDMat.Brush = new SolidColorBrush(_trackMesh.TrackMeshObjects[a].ObjectColor);

        // thread owner exception
        _mgTrack.Children.Add(new GeometryModel3D(mGeom, mDMat));
    }

问题是我正在读取对象(Point3DCollection / Int32Collection)而不是从背景填充的对象中复制的普通值吗?
是不是这样当你在线程之间共享数据时,你必须在另一个线程中创建你想要使用的所有数据的副本(在其他对象中,即 MeshGeometry / Modelgroup)?我们可以不在后台填充一个对象,然后在填充完成后在另一个线程中“简单地使用它”吗?

4

2 回答 2

0

与此同时,我通过使用普通的 Point3D[] 和 int[] 数组而不是 xxxCollection 对应物来解决了这个问题。然后,当我用这些数组填充 3D 模型时,它工作正常。没有线程所有权错误。奇怪......但显然某些对象(已在后台线程上创建)根本无法在另一个线程中访问,或者我错过了一些东西(可能 - 我只使用 c# 1.5 个月)。

于 2010-11-19T21:13:47.587 回答
0

一个简单而肮脏的尝试是将函数指针(委托回调)传递给您从 gui 线程启动的线程的上下文。当您想将它读回 gui 线程时,该委托实质上将返回您想要读取的任何内容。所以回调是在主线程上创建的。这应该有效。

于 2010-11-19T19:43:32.390 回答