Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一个单独的线程中加载多个三维几何图形,而不遇到线程所有权问题?_C#_.net_Wpf_Multithreading_Xaml - Fatal编程技术网

C# 如何在一个单独的线程中加载多个三维几何图形,而不遇到线程所有权问题?

C# 如何在一个单独的线程中加载多个三维几何图形,而不遇到线程所有权问题?,c#,.net,wpf,multithreading,xaml,C#,.net,Wpf,Multithreading,Xaml,我有几个MeshGeometry3D元素存储在单独的文件中。例如,somemodel.xml可能包含 如果我在主UI线程中加载它们,它们会在加载时锁定UI。因此,我尝试将它们加载到单独的线程中: ThreadStart threadStart = delegate { var geometry = ConvertXmlFileToMeshGeometry3D(filename); viewport2DVisual3D.Dispatcher.BeginInvoke(

我有几个
MeshGeometry3D
元素存储在单独的文件中。例如,
somemodel.xml
可能包含

如果我在主UI线程中加载它们,它们会在加载时锁定UI。因此,我尝试将它们加载到单独的线程中:

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);
但是,这在
viewportVisual.Geometry=Geometry一行中给出了一个异常
调用线程无法访问此对象,因为其他线程拥有它。

换句话说,
MeshGeometry3D
是在不同的线程上创建的,因此我无法将其作为
Viewport2DVisual3D
的几何体

我无法找到一种方法来异步加载
MeshGeometry3D
s,而不让错误的线程拥有它们。这仅仅是不可能的事情,还是有办法做到这一点

编辑:评测表明,加载
MeshGeometry3D
的时间大约有13%用于从文件加载xml元素(
var element=XElement.load(filename);
),其余时间用于将其转换为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看起来并不是这里的瓶颈。

除非您以后需要修改模型,您可以在加载模型后尝试修改它,然后可以跨线程共享它,请参见。

什么是“锁定”UI的操作?是从磁盘获取XML所花的时间,还是将XML转换为几何体对象所花的时间,还是什么?(我问这个问题的原因是,可能有某种方法可以使用基于任务的异步将工作分解为更小的部分,然后可以在UI线程上按顺序完成,但不会使UI消息循环处于饥饿状态。)@Eric Lippert我认为问题不在于UI线程阻塞,但是WPF要求在UI线程上执行某些操作,这当然也会导致UI线程阻塞:)@Eric:请参阅我的编辑。根据我的评测,从磁盘获取XML并将其转换为
XElement
,从文件加载
MeshGeometry3D
只需要总时间的13%左右。谢谢,我以后不需要修改模型,所以这非常有效。