c# - 在主线程忙时连续更新UI

标签 c# .net multithreading winforms

我要在MainForm进行一些数据库相关工作时显示带有进度栏的新表单。我读到您不想将UI传递给新线程,所以我想知道解决此问题的最佳解决方案是什么?

我无法在另一个线程上执行与数据库相关的工作,因为它使用了十二个对UI和MainForm的调用。我也不能使用Application.DoEvents(),因为MainForm的线程正在类中工作,据我所知,您不应对类的父类进行任何调用。

任何建议,将不胜感激!

编辑

为了澄清我实际上想知道的事情:

我的程序看起来像这样:

... Content = DatabaseClass.LoadContent();
ApplyContentToUI(Content);

我想做的是以下几点:
//Show a form here with a progressbar
... Content = DatabaseClass.LoadContent();
ApplyContentToUI(Content);
//Close the form here

但是,自从执行ApplyContentToUI的时间开始就是aprox。我希望1秒钟执行以下操作:
//Show a form here with a progressbar
... Content = DatabaseClass.LoadContent();
//Close the form here
ApplyContentToUI(Content);

如果您与我不同,如果需要在重新加载UI时显示进度栏,建议您查看下面的评论和答案。

最佳答案

I can't do the database related work on another thread


错误的。
推荐:
正如许多评论中提到的那样,您应该重构代码以将业务逻辑与UI逻辑分开。每个.NET版本都有已知的模式和实践,这将导致清晰的分离。我整理了一些工具及其指向用法的链接,供您查看。
工具:
BeginInvoke
  • Control.BeginInvoke 方法可用于异步操作(.NET 2.0+)。
  • BeginInvoke用于在控件源自的线程上异步运行代码。如果发起线程是UI线程,这将允许进行UI操作。 BackgroundWorker使用它来ReportProgress。这将允许UI在长时间运行的操作发生时保持响应。
    这不应直接嵌入业务逻辑中。但是,它可以用于将消息中继回UI线程。
    看:
  • Diffrernce between BackgroundWorker.ReportProgress() and Control.BeginInvoke()

  • 后台 worker
  • BackgroundWorker 将在单独的线程上运行工作,并且它具有事件驱动的进度(.NET 2.0+)。
  • BackgroundWorker是一个事件驱动的控件,它将在另一个线程上执行代码。它具有内置的功能,可以使用 ReportProgress 向监听器通知进度。
    在后台BackgroundWorker使用Control.BeginInvoke作为ReportProgress,从而可以有效分离业务逻辑。
    看:
  • How to use a BackgroundWorker?
  • How to use a background worker for Windows Phone

  • 调度员
  • Dispatcher 可以将操作中继到UI线程(.NET 3.0+)。
  • Dispatcher是为WPF添加的,但仍可以在WinForms中使用(尽管不太理想)。 Dispatcher的功能与BeginInvoke相同,并且可以同步运行或异步运行。
    看:
  • System.Windows.Threading.Dispatcher and WinForms?

  • 任务
  • 通过 Task(T) 类,可以很容易地将逻辑与UI线程交织在一起。 (带有TPL包的.NET 4.0 + 、. NET 3.5+)。

  • 添加了任务并行库以提供一组并行性和并发性抽象。 Task是消息驱动的,并允许封装非阻塞操作。这也是.NET 4.5 async/await模式的基础。Task用于流式处理操作,以便可以将它们链接在一起并产生结果。比BackgroundWorker更加简化,并且可以更好地进行操作组合。这也使producer-consumer scenarios的实现更加简单。
    看:
  • WinForms TPL Pattern w/ Multiple Tasks & UI Sync - is this correct?
  • How to update UI from child tasks in WinForms
  • Producer Consumer model using TPL, Tasks in .net 4.0
  • 关于c# - 在主线程忙时连续更新UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17531106/

    相关文章:

    c# - 单元测试 Microsoft Band

    c# - 在 MVVM WPF 中将 DataTable 绑定(bind)到 DataGrid

    c# - 如何将 android Unity 错误和调试日志导出到文件?

    c# - 反序列化 XML 文件而不将其全部加载到内存中

    java - 将 .Net RSA xml key 移植到 Java

    linux - 如何将 "force"单线程遗留应用程序转为使用多个处理器

    java - 没有 final 修饰符,Initialization On Demand Holder 成语线程安全吗

    python - 有什么办法可以杀死一个线程吗?

    c# - Monitor.Pulse/Wait 的异步版本

    c# - 是否可以在 C# 中观察 Rss 提要的变化?