Rob*_*bin 1 .net c# multithreading winforms
我想在我的MainForm正在进行一些与数据库相关的工作时显示带有Progressbar的新表单.我已经读过你不想将UI传递给新的线程,所以我想知道解决这个问题的最佳解决方案是什么?
我无法在另一个线程上执行与数据库相关的工作,因为它使用了对UI和MainForm的十几个调用.我也无法使用,Application.DoEvents()因为MainForm的线程在类中工作,据我所知,你不应该对类的父类进行任何调用.
任何建议,将不胜感激!
编辑
澄清我实际想知道的事情:
我的程序看起来有点像这样:
... Content = DatabaseClass.LoadContent();
ApplyContentToUI(Content);
Run Code Online (Sandbox Code Playgroud)
我想做的是以下内容:
//Show a form here with a progressbar
... Content = DatabaseClass.LoadContent();
ApplyContentToUI(Content);
//Close the form here
Run Code Online (Sandbox Code Playgroud)
但是,因为执行ApplyContentToUI的时间是aprox.1秒我决定做以下事情:
//Show a form here with a progressbar
... Content = DatabaseClass.LoadContent();
//Close the form here
ApplyContentToUI(Content);
Run Code Online (Sandbox Code Playgroud)
如果您和我不同,需要在重新加载UI时显示进度条,我建议您查看下面的注释和答案.
我不能在另一个线程上做数据库相关的工作
假.
正如许多人在评论中提到的那样,您应该重构代码以将业务逻辑与UI逻辑分开.每个.NET版本都有已知的模式和实践,可以实现清晰的分离.我已经汇总了一些工具和链接到他们的用法供您查看.
Control.BeginInvoke 方法可用于异步操作(.NET 2.0+).BeginInvoke用于在控件源自的线程上异步运行代码.这将允许在原始线程是UI线程的情况下发生UI操作.BackgroundWorker用这个来ReportProgress.这将允许UI在长时间运行操作时保持响应.
这不应该直接嵌入业务逻辑中.但是,它可用于将消息中继回UI线程.
看到:
BackgroundWorker 将在一个单独的线程上运行,它具有事件驱动的进展(.NET 2.0+).这BackgroundWorker是一个事件驱动的控件,它将在另一个线程上执行代码.它具有内置功能,可以向使用者通知进度ReportProgress.
幕后的BackgroundWorker用途Control.BeginInvoke为ReportProgress,允许商业逻辑的有效分离.
看到:
Dispatcher可以中继操作UI线程(.NET 3.0+);这Dispatcher是为WPF添加的,但它仍然可以在WinForms中使用(尽管它不太理想).在Dispatcher以同样的方式将功能BeginInvoke,它可以同时运行同步或异步.
看到:
Task(T)类简化了交织逻辑关闭UI线程.(.NET 4.0 +,带有TPL包的.NET 3.5+).添加了任务并行库以提供一组并行和并发的抽象.Task是一种消息驱动,允许封装非阻塞操作.这也是.NET 4.5 async/ await模式的基础.
Task用于流操作,以便它们可以链接在一起并产生结果.这比BackgroundWorker它更简化,并且它允许更好的操作组合.这也使得实施生产者 - 消费者情景更加简单.
看到:
| 归档时间: |
|
| 查看次数: |
3355 次 |
| 最近记录: |