Как я могу загрузить несколько трехмерных геометрий в отдельном потоке, не сталкиваясь с проблемами владения потоком? - PullRequest
2 голосов
/ 29 июня 2011

У меня есть несколько 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 с диска является узким местом здесь.

1 Ответ

4 голосов
/ 29 июня 2011

Если вам не понадобится изменить модель позже, вы можете попробовать Freeze после ее загрузки, затем ее можно будет разделить между потоками, см. Обзор Freezable Objects .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...