我使用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)?
答案 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
了解详情