【问题标题】:C# UI "Not responding" stops Refresh()C# UI“无响应”停止 Refresh()
【发布时间】: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


【解决方案1】:

最好将其移至单独的线程。尽管这种行为并非没有价值,但我怀疑这种解决方案的可维护性最终会迫使人们重新思考。

您只需在 UI 顶部显示一个面板以阻止对所有功能的访问,即可获得所有“好处”。在此面板上,您可以显示进度条和状态消息,这样用户就不会太害怕了。

我认为现在值得投资以提供更完善的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多