如何在线程之间传递GeometryCollection

时间:2016-07-01 11:26:12

标签: c# wpf multithreading data-binding

我的情况:

我想绘制一个由不同图层组成的地图。

到目前为止,我使用ItemsControl来显示所有图层:

<ItemsControl ItemsSource="{Binding Layers}"
              ItemTemplate="{StaticResource LayerViewTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

我使用的模板如下所示:

   <DataTemplate x:Key="LayerViewTemplate"
                 DataType="{x:Type data:InformationLayer}">
       <Path StrokeThikness="{Binding W}"
             Stroke="Black"
             Data = {Binding Data}/>
   </DataTemplate>

如您所见,类InformationLayer包含一个图层的所有数据。这包括财产:

public GeometryGroup Data { get; protected set; }

生成图层是一个漫长的过程。 我必须阅读一堆文件等。 这就是为什么我想在异步函数中做到这一点。

问题:

GeometryGroup对象属于创建它们的线程。 因此,如果我使用不同的线程来创建我的图层,它们将属于该线程。 我希望它们属于我的主要线程,因为我想将它们用作绑定源。 是否有可能将GeometryGroup从一个线程移动到另一个线程?

到目前为止,生成我的图层的功能如下所示: 但最后一行抛出一个异常,因为wpf不想绑定到一个在另一个线程中生成的对象。

    protected async void generateLayers()
    {
        var progress = new Progress<RefreshLayersProgressReport>(ReportLayerProgress);
        var ans =  await Task.Run(() => refreshLayers(progress));

        Layers = ans;
    }

1 个答案:

答案 0 :(得分:1)

GeometryGroup源自Freezable。因此,在调用Freeze()方法后,它应该是跨线程可访问的。

来自Freezable页面上的主题安全部分:

  

当IsFrozen属性为false时,可以使用Freezable对象   只能从创建它的线程访问。试图   从另一个线程访问它会抛出InvalidOperationException。该   Dispatcher.Invoke和Dispatcher.BeginInvoke方法提供支持   用于编组到正确的线程。

     

当他们的IsFrozen属性为true时,Freezable对象就是   自由线程。有关更多信息,请参阅Freezable Objects Overview。