【发布时间】:2014-10-01 13:33:33
【问题描述】:
如果主 UI 线程花费的时间过长,窗口将启动“无响应”。这不是问题 - 事实上,它实际上有几个优点,例如使 UI 不响应,以及有效地“缓存”输入直到长操作完成之后。
但是,这种状态会使 Refresh() 函数停止工作。状态消息、进度条等停止更新。澄清一下,导致这种情况的不仅仅是长时间的操作本身。我可以坐下来观看长时间的手术(大约需要一分钟),一切都很完美。用户界面在刷新时正确更新,一切都很好。
但是,如果我左键单击标题栏,例如,这会触发“无响应”状态,由于某种原因,这会阻止任何 Refreshes 重新绘制(它们仍在被调用)。
将长操作放入 BackgroundWorker 线程将是前进一步,后退三步。我可以忍受进度条不更新等情况,但它能够正确更新真的很好,即使“没有响应”也是如此。
鉴于“挂起”的 UI 在长时间操作期间非常乐意更新/刷新/重新绘制 UI,那么肯定有办法让它继续这样做,即使它被设置为“无响应”?
另外,调用 Application.DoEvents() 有很多缺点(就像处理消息一样,它应该缓存以供以后使用),所以我也不能这样做。
【问题讨论】:
-
线程是您唯一的解决方案,您不能期望在 UI 线程上执行长时间操作并期望它保持响应。 BackgroundWorker 有什么问题?它有一个report progress 方法可以解决您提到的查询
-
我不明白为什么“不要在 UI 线程中进行同步长时间运行的工作”的绝对标准方法在这里不适用。在工作进行时拥有响应式 UI(可以最小化、移动等)会以何种方式“退后三步”?
-
@Sayse:嗯,线程可能不是唯一的解决方案。我们不知道工作是什么。如果它是 IO 绑定的,那么 async/await 可能能够将所有工作保持在一个线程上,但不会阻塞。
-
@JonSkeet - 非常正确,无论哪种方式,我都不同意 OP 反对 BackgroundWorker 的论点
-
Given that the "hung" UI is perfectly happy updating/refreshing/repainting the UI during long operations, surely there is a way to have it keep doing that您的应用可能没有重新绘制自己。当您在标题栏 (Windows) 中看到“(未响应)”时,操作系统可能已经接管了该窗口的重绘(使用后备存储),因为程序没有响应
标签: c# user-interface refresh