【发布时间】:2016-09-03 05:04:34
【问题描述】:
我使用 Canvas 作为数千个 DrawingVisuals 的宿主。加载速度非常慢。我尝试仅加载开始时可见的 DrawingVisuals 并异步加载并等待其他 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)?
【问题讨论】:
-
当我使用 Visual Studio 2010 时,我没有使用过 async/await,但
Dim visuals = Await CreateVisuals()不会解决问题吗?或者只是Dim visuals = CreateVisuals()因为 CreateVisuals() 应该阻塞当前线程直到它返回。 -
但我不想阻塞当前线程。绘制所有视觉效果需要太长时间并且会阻塞 UI。
-
那你为什么用
Await? -
我希望当前不可见的 DrawingVisuals - 稍后它们可以通过滚动变得可见 - 在后台加载而不阻塞 UI。
-
那么您必须首先删除该函数并循环创建它们的代码。在该代码的末尾,在它开始创建下一个视觉对象之前,您调用
AddVisualChild()和AddLogicalChild()。
标签: vb.net multithreading asynchronous async-await