【问题标题】:Update UI control from another thread while the UI is busy for time-consuming work在 UI 忙于耗时工作时从另一个线程更新 UI 控件
【发布时间】:2016-01-07 15:57:24
【问题描述】:

我的问题是如何在 UI 线程忙于查询数据库时从另一个线程更新 UI 控件(例如 ProgressBar)(运行耗时的存储过程)?


我检查了这些问题,但仍然没有找到适合我的解决方案。

  1. Updating UI continuously while the main thread is busy
  2. How to update the GUI from another thread in C#?
  3. Run multiple UI Threads
  4. Cross-thread cross-form. Display a splash screen with a progress bar

我知道一种选择是使用 BackgroundWorker 进行耗时的工作,并使用 更新 ProgressBar >ReportProgress 方法,但是我在这个选项中有一个问题,因为 UI 线程负责实例化并在查询数据库后显示另一个表单,如下所示:

Form2 f2=new Form2();
f2.show();

【问题讨论】:

  • 我也在主UI线程+填充视图(wpf)中查询数据库,所以这部分没问题。问题是 - 你不能更新那个 UI,因为它很忙。您可以使用DoEvents,但我发现另一个线程中的另一个窗口效果最好。好吧,至少对我来说是这样(但在 wpf 中)。见further
  • 我不明白为什么你不能在辅助线程上做任何耗时的事情,然后在主线程上打开表单。也许你应该在主线程忙时(如果可能的话)强制刷新 UI 之前考虑这一点。
  • 你刚刚指出了你的缺陷。永远不要从主 UI 线程查询数据库!

标签: c# multithreading winforms


【解决方案1】:

我建议您使用BackgroundWorker,并将Form2 对象的构造和表示放在BackgroundWorkerRunWorkerCompleted 事件处理程序中,该处理程序在BackgroundWorker 完成时在UI 线程上执行。绝对不要尝试从后台线程更新 UI。 GUI 类不是线程安全的。

【讨论】:

  • 感谢您的回答,对于耗时的工作显示Form2而我仍然需要在该工作期间更新主窗体的ProgressBar的情况,您有什么建议?
  • 所以你是说“耗时的工作”需要用户在执行过程中输入?也有办法解决这个问题。 Control.Invoke 可以让你在 GUI 线程上运行代码,同时阻塞调用线程。
  • 我们可以为我的场景假设登录表单;用户输入用户名并通过,我检查登录信息并显示 Form2,但 Form2 是 UI 丰富的,需要 10-12 秒才能加载,在此期间,我想在主窗体中更新 ProgressBar,我清楚吗?
  • 如果 Form2 需要很长时间才能加载纯粹是因为它有这么多控件(值得怀疑),那么您真的无能为力。所有工作都必须在 UI 线程上完成,因此您的 UI 线程必须等待。相反,如果 Form2 在初始化时执行了大量 IO 或与 GUI 无关的操作,您也可以将这项工作放在后台线程上。
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
相关资源
最近更新 更多