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%左右。谢谢,我以后不需要修改模型,所以这非常有效。