我想在主UI线程上做一些工作时显示带进度条的模态对话框。如果不使用任何多线程技术,我的UI肯定会处于挂起状态。
如何在主线程上运行计算密集型长操作时实现这一点(因为它涉及UI元素,我不愿触摸这个遗留代码),同时在等待窗口上显示计算的状态(将运行在另一个线程上)
我需要在不同的线程上运行进度对话框窗口,同时保持主线程被占用以计算涉及主UI表单元素的长绑定操作。
感谢您的一些指示
答案 0 :(得分:1)
UI无法在不同的线程中运行。它应该在UIThread中运行。您将不得不在不同的线程中重写强烈的操作,并使用调度程序将参数传递给它(因为UI元素可以从我提到的UI线程访问)。如果您阻止主线程,您将无法显示进度。
答案 1 :(得分:1)
如果您的问题是在运行该长任务时向用户更新状态(进度条),则解决方案为In Control.CheckForIllegalCrossThreadCalls = false
社区建议不要将该属性设置为false,但我喜欢从任何线程访问所有控件并且它工作正常并且它是直接向前的,除非有人给我们一个不使用它的好理由而不是“它的使用不好改为调用“。
private void button1_Click(object sender, EventArgs e) {
//To avoid Cross-thread exception
Control.CheckForIllegalCrossThreadCalls = false;
//Start background task
bkg.RunWorkerAsync();
//show wait form
var frmWait = new WaitForm();
frmWait.ShowDialog();
}
private void bkg_DoWork(object sender, DoWorkEventArgs e) {
//Do your work and update status
}
答案 2 :(得分:0)
技术上可以在UI线程以外的线程上创建模型对话框(但当然不可取)
无论如何,既然你无法改变遗留代码,并希望模型对话框能够在另一个线程上工作,那么这是一个建议
1>创造&在单独的线程上打开“模型”对话框
2 - ;计算密集型工作必须触发一些可以挂钩报告进度的事件。这些事件是从UI线程触发的,您必须将它们编组到创建此模型对话框的线程中。使用Control.InvokeRequired
检测调用堆栈来自另一个线程&使用control.Invoke(action)
来编组