我怎么可以加载在一个单独的线程数三维几何图形没有运行到线程所有权问题?线程、几何图形、所有权、加载

2023-09-04 04:36:19 作者:花溪信马

我有存储在独立的文件数 MeshGeometry3D 元素。例如, somemodel.xml 可能包含< MeshGeometry3D ... />

I have several MeshGeometry3D elements that are stored in separate files. For example, somemodel.xml might contain <MeshGeometry3D ... />.

如果我在主UI线程加载它们,它们锁定用户界面,而他们加载。所以,我试着加载他们在一个单独的线程:

If I load them in the main UI thread, they lock up the UI while they load. So I've tried loading them in a separate thread:

ThreadStart threadStart = delegate
{
    var geometry = ConvertXmlFileToMeshGeometry3D(filename);
    viewport2DVisual3D.Dispatcher.BeginInvoke(
        DispatcherPriority.Normal,
        new Action(delegate { viewport2DVisual3D.Geometry = geometry; }));
};
threadStart.BeginInvoke(delegate(IAsyncResult aysncResult) { threadStart.EndInvoke(aysncResult); }, null);

不过,这给出了一个例外,就行了 viewportVisu​​al.Geometry =几何; 调用线程不能访问此对象,因为不同的线程拥有吧。

在换句话说, MeshGeometry3D 是在不同的线程创建的,所以我不能让它的 Viewport2DVisual3D 小号几何。

In other words, the MeshGeometry3D was created on a different thread, so I cannot make it the Viewport2DVisual3D's Geometry.

我不能想出一个办法来异步加载 MeshGeometry3D •不用他们正在错误的线程所拥有。这只是东西是不可能的,或者是有办法做到这一点?

I can't figure out a way to asynchronously load the MeshGeometry3Ds without them being owned by the wrong thread. Is this just something that is not possible, or is there a way to do it?

编辑:概要分析表明,大约13%的时间来加载 MeshGeometry3D 花在从文件加载XML元素( VAR元素= XElement.Load(文件名); ),其余的是花在其转换为MeshGeometry3D:

Profiling suggests that about 13% of the time to load a MeshGeometry3D is spent loading the xml element from the file (var element = XElement.Load(filename);), and the rest is spent converting it to a MeshGeometry3D:

return new MeshGeometry3D
{
    Normals = (Vector3DCollection)new Vector3DCollectionConverter().ConvertFromString(element.Attribute("Normals").Value),
    Positions = (Point3DCollection)new Point3DCollectionConverter().ConvertFromString(element.Attribute("Positions").Value),
    TextureCoordinates = (PointCollection)new PointCollectionConverter().ConvertFromString(element.Attribute("TextureCoordinates").Value),
    TriangleIndices = (Int32Collection)new Int32CollectionConverter().ConvertFromString(element.Attribute("TriangleIndices").Value),
};

所以它看起来并不像从磁盘获取XML是瓶颈在这里。

So it doesn't look like fetching the XML from disk is the bottleneck here.

推荐答案

除非你需要修改模型后,你可以尝试的 冻结 它已经加载之后,那么就可以翻过线程共享,看到的 Freezable对象概述

Unless you need to modify the model later you can try to Freeze it after it has been loaded, then it can be shared accross threads, see Freezable Objects Overview.