BackgroundWorker更新GUI

时间:2011-11-29 20:13:29

标签: c# wpf silverlight asynchronous

在我的Silverlight应用程序中,我有一个操作需要几秒钟并与GUI强烈交互(在一个大的“for”语句中创建显示对象)

起初我想过使用BackgroundWorker来避免冻结界面。但我不能直接更新GUI,所以我使用了Dispatcher.BeginInvoke,但它仍然冻结了界面(因为长动作在gui部分)。

我想要的是在加载我的对象时显示BusyIndi​​cator,但我希望用户能够在加载时继续工作。

我还能做什么?有什么建议吗?

2 个答案:

答案 0 :(得分:5)

即使是忙碌的图标也无法帮到你。繁忙的图标或任何其他图形项需要UI线程来泵送消息以便不“冻结”UI。如果长时间运行的操作在UI线程上运行,那么即使繁忙的光标也会“冻结”。

你需要

  1. 将昂贵的长时间运行逻辑移至后台线程
  2. 将UI逻辑分解为块,让UI在它们之间刷新。

答案 1 :(得分:4)

在BackgroundWorker中创建UI项目是错误的。如果从BackgroundWorker运行,则创建UI元素需要切换回UI线程。这只会比在主线程上创建它们更糟糕。

我认为BackgroundWorker中的许多工作都不是创建元素,而是在其他所有内容中创建UI元素时会发生一些额外的处理。
如果是这种情况,您需要打破实际生成的UI元素。使用包含构建所有元素所需的所有规范的dummy类替换UI元素的生成。然后返回规范集合(虚拟类)并在BackgroundWorker.RunWorkerCompleted事件中生成实际元素。