чтение данных из объекта, который заполнен из другого потока - PullRequest
0 голосов
/ 19 ноября 2010

Язык: c # (wpf)

Ситуация: мне нужно загрузить трехмерную сетку из файла, после чего я заполняю Viewport3D.

Что я хочу сделать: я хочу загрузить 3D-сетку в BackgroundWorker, чтобы приложение не зависало при загрузке 3D-сетки; это займет несколько секунд.

Проблема: проблема НЕ в том, как использовать BackgroundWorker. Это хорошо задокументировано. Проблема возникает, когда я хочу заполнить Viewport3D Model3DGroup (группа 3D-объектов).

При загрузке 3D-сетки из файла, в фоновом режиме я заполняю пользовательский класс сетки всеми точками и индексами треугольников каждого объекта в сетке. Я храню их в Point3DCollections и Int32Collections соответственно.

public class LFSMeshObject
{
    public Point3D Center;
    public int Radius;
    public int NumPoints;
    public int NumTris;

    public Color ObjectColor { get; private set; }
    public Point3DCollection Points { get; private set; }
    public Int32Collection Tris { get; private set; }

Когда этот заполненный объект передается обратно в поток графического интерфейса, я могу прекрасно прочитать все значения и свойства, хранящиеся в объекте. Я также могу прочитать Point3Dcollections и Int32Collections, которые я копирую в MeshGeometry3D, которые входят в Model3DGroup, но затем получают исключение для владельца потока, поскольку свойства заполненного фонового объекта принадлежат фоновому потоку.

    DiffuseMaterial mDMat;
    MeshGeometry3D mGeom;
    Debug.WriteLine("num objects in mesh : {0}", _trackMesh.NumObjects);
    for (int a = 0; a < _trackMesh.NumObjects; a++)
    {
        mGeom = new MeshGeometry3D();
        mGeom.Positions = _trackMesh.TrackMeshObjects[a].Points;
        mGeom.TriangleIndices = _trackMesh.TrackMeshObjects[a].Tris;

        mDMat = new DiffuseMaterial();
        mDMat.Brush = new SolidColorBrush(_trackMesh.TrackMeshObjects[a].ObjectColor);

        // thread owner exception
        _mgTrack.Children.Add(new GeometryModel3D(mGeom, mDMat));
    }

Проблема в том, что я читаю объекты (Point3DCollection / Int32Collection) вместо простых значений, которые будут скопированы из объекта, заполненного фоном?
Это так, что когда вы обмениваетесь данными между потоками, вам нужно создавать копии всех данных, которые вы хотите использовать (в другом объекте, т.е. MeshGeometry / Modelgroup) в другом потоке? Разве мы не можем заполнить объект в фоновом режиме и затем «просто использовать его» в другом потоке после завершения заполнения?

Ответы [ 2 ]

0 голосов
/ 20 ноября 2010

Тем временем я исправил проблему, используя обычные массивы Point3D [] и int [] вместо аналогов xxxCollection.Затем, когда я заполняю 3D-модели этими массивами, все работает нормально.Нет ошибок владения потоком.Странно ... но, очевидно, некоторые объекты (созданные в фоновом потоке) просто не могут быть доступны в другом потоке, или я что-то упускаю (возможно - я использую c # только 1,5 месяца).

0 голосов
/ 19 ноября 2010

Простая и грязная вещь, которую стоит попробовать - передать указатель на функцию (обратный вызов делегата) в контекст потока, который вы запускаете из потока GUI. Этот делегат, по сути, вернет все, что вы хотите прочитать, именно в тот момент, когда вы захотите прочитать его обратно в поток графического интерфейса. Таким образом, обратный вызов создается в главном потоке. Это должно работать.

...