如何使用Async和Await异步加载DrawingVisual?

时间:2016-05-08 14:29:21

标签: vb.net multithreading asynchronous async-await

我使用Canvas作为数千个DrawingVisuals的主机。加载速度很慢。我试图只加载at start可见的DrawingVisuals并使用async并等待其他DrawingVisuals:

Async Sub AddVisuals()
    Dim visuals = Await Task.Run(AddressOf CreateVisuals)
    For Each vis In visuals
        AddVisualChild(vis)
        AddLogicalChild(vis)
    Next
End Sub
Function CreateVisuals() As DrawingVisual()
    ....
End Function

但是Task.Run调用另一个线程。所以我得到一个InvalidOperation异常,声明该对象归另一个线程所有。 但here我发现:

  

async和await关键字不会导致其他线程被创建。异步方法不需要多线程,因为异步方法不能在自己的线程上运行。该方法在当前同步上下文上运行,并仅在方法处于活动状态时在线程上使用时间。您可以使用Task.Run将受CPU限制的工作移动到后台线程,但后台线程对于只等待结果可用的进程没有帮助。

那么,有没有办法用async和await添加DispatcherObject(这里:DrawingVisual)?

2 个答案:

答案 0 :(得分:1)

我找到了一个解决方案:visual.Dispatcher.InvokeAsync(Sub() DrawVisual)是等待的。所以我和Await一起使用它。 (在DrawVisual中调用RenderOpen)现在所有DrawingVisual都加载得更快,UI不再被阻止。感谢Visual Vincent和Scott的帖子。

答案 1 :(得分:0)

为了达到你的目标,我希望目前不可见的DrawingVisuals - 后来它们可以通过滚动显示 - 在后台加载而不会阻止UI"我建议你尝试使用UI虚拟化而不是异步...等待。

将容器控件的IsItemsHost属性设置为True,然后可以将ItemsPanel属性设置为VirtualizingStackPanel并将IsVirtualizing设置为true。

https://msdn.microsoft.com/en-us/library/cc716879(v=vs.100).aspx

了解详情