У меня есть несколько MeshGeometry3D
элементов, которые хранятся в отдельных файлах. Например, somemodel.xml
может содержать <MeshGeometry3D ... />
.
Если я загружаю их в основной поток пользовательского интерфейса, они блокируют пользовательский интерфейс во время загрузки. Поэтому я попытался загрузить их в отдельном потоке:
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;
: The calling thread cannot access this object because a different thread owns it.
Другими словами, MeshGeometry3D
был создан в другом потоке, поэтому я не могу сделать его геометрией Viewport2DVisual3D
.
Я не могу найти способ асинхронной загрузки MeshGeometry3D
без того, чтобы они принадлежали не тому потоку. Это просто невозможно, или есть способ сделать это?
Редактировать: Профилирование предполагает, что около 13% времени на загрузку MeshGeometry3D
тратится на загрузку элемента 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 с диска является узким местом здесь.