在另一个线程中使用WPF多边形

3

当我将一个类型为Dictionary(Of Int16, Polygon)的对象作为参数传递给后台工作者时,我遇到了一个问题,因此后台工作者能够访问字典中的多边形。我得到了典型的“调用线程无法访问此对象,因为不同的线程拥有它”的消息。这是我的代码:

                Dim worker As New BackgroundWorker
                AddHandler worker.DoWork, AddressOf MeasurePolygons
                AddHandler worker.RunWorkerCompleted, AddressOf WorkerCompleted

                worker.RunWorkerAsync(PolygonCollection)

PolygonCollection是该类顶部声明的一个私有变量,类型为Dictionary(Of Int16, Polygon)。它将包含1-10个多边形,并且我想将此集合传递给BackgroundWorker,因为我要对字典中的每个多边形进行计算。

    Dim TempPolygonCollection As Dictionary(Of Int16, Polygon)
    TempPolygonCollection = CType(e.Argument, Dictionary(Of Int16, Polygon))
    For i = 0 To TempPolygonCollection.Count - 1
            If TempPolygonCollection.ContainsKey(CShort(i)) Then
                Dim rtb As New RenderTargetBitmap(CInt(800), CInt(600), 96D, 96D, PixelFormats.Default)
                rtb.Render(TempPolygonCollection.Item(CShort(i)))
                Dim encoder As New BmpBitmapEncoder
                encoder.Frames.Add(BitmapFrame.Create(rtb))
            End If
    Next i

错误出现在rtb.Render(TempPolygonCollection.Item(CShort(i)))。非常感谢任何帮助。

编辑: 所以这两位友好的张贴者帮我缩小了问题的范围,但我仍然不知道如何解决它。

当前问题:我有一个类型为Dictionary(Of Int16, Polygon)的对象。我需要能够访问此字典中创建在UI线程上的每个单独的多边形。然后,在后台工作程序中,我将基于字典中的多边形创建位图文件。那么我该如何在后台工作程序中访问这些多边形?感谢任何帮助。


我冒昧修改了你的问题标题。也许这样会吸引一些知道这些事情的人... - Heinzi
2个回答

1

问题不在于Dictionary,而在于存储在其中的Polygon。这些是在UI线程中创建的WPF UI元素,因此只有UI线程才能使用它们。

您可以将Render操作执行到UI线程中(使用Dispatcher.Invoke)。这意味着渲染会阻塞您的UI线程,但至少在渲染操作之间,UI线程将能够处理其他事情,即使单个渲染操作所需的时间不太长,UI也应该保持响应。


有趣..那么我需要做什么才能使它们或它们的副本可以被后台工作者访问? - devman
我正在将这些多边形转换为位图文件。因此,我有意地尝试在后台线程上创建位图,因为从10个不同的多边形中创建10个位图可能需要10-15秒左右的时间。因此,我使用UI线程显示加载动画,以向用户提供反馈,告诉他们它没有冻结。 - devman
@bflosabre:你能否在后台线程中创建多边形呢? - Heinzi
这些多边形是基于用户在InkCanvas上输入的内容创建的。因此,用户基本上绘制一个形状,点击一个按钮,多边形就会根据InkCanvas中的笔画被创建出来。所以我不确定如何在后台线程中创建这些多边形。 - devman
1
@bflosabre91:我明白了。是的,听起来很困难。我能想到的唯一办法就是将多边形中所有相关信息取出,传递给后台线程,在那里重新创建一个多边形。例如,多边形的点集合(Polygon.Point)是可冻结的,这意味着您可以在 .Freeze 后将其跨线程边界传递(http://msdn.microsoft.com/en-us/library/ms750509.aspx)。抱歉,目前想不到更好的解决方案。 - Heinzi

1
问题在于在WPF中,Polygon对象不能在创建它们的线程以外的线程上使用。这意味着您无法访问它们的任何属性,或尝试将它们渲染到RenderTargetBitmap中。
如果您正在尝试在渲染所有这些图像时不阻塞UI,则建议使用Dispatcher来分解工作(将它们调度为Background优先级)。这样,在UI线程上发生单个保存时,Dispatcher可以交错鼠标输入、渲染等,因此UI不会被阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接