在我的用户界面中,当按下按钮时,将执行以下代码:
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.RunWorkerAsync();
第一次成功.当我按下按钮(然后将其禁用)时,我仍然可以在后台任务执行期间四处移动窗口并单击内容.但是,当后台工作人员完成(再次启用按钮)并再次按下它时,后台工作人员将运行,但我不再拥有对窗口的控制权.
我不知道为什么这第二次不起作用.在后台工作程序运行之前或之后,是否需要做一些事情以确保它不会阻塞UI线程?
谢谢!
编辑:在backgroundworker ProgressChanged处理程序中,我更新了进度条和文本标签,显示了沿着背景工作程序的距离.它们不断更新,永不冻结.但是,当我尝试拖动窗口或单击其他控件时,它们只会定期响应.
后台工作人员访问类的实例,该类的实例是UI线程中的全局变量.想法是实例化对象,从后台工作人员的DoWork内部运行对象执行的长函数,然后在后台工作人员完成查看结果后访问该对象.这样可以吗?
在后台工作人员的DoWork中调用的该对象的函数内部,可以访问几个静态类.这会导致任何线程问题吗?
解决方法:
您可以通过两种方式使用BackgroundWorker.
>通过将其从工具箱拖放到表单并在属性窗口中设置其属性和事件.
>通过编程定义它.
可能您混合了两种方法.
如果您使用第一种方法,则删除所有初始化代码(表单会自动为您完成!)并仅调用
backgroundWorker1.RunWorkerAsync();
如果要使用第二种方法,请不要将其放在表单上.而是将其声明为成员变量.能够将其作为组件添加到表单的唯一目的是通过属性窗口启用设置属性和事件. BackgroundWorker不需要表格中的任何内容,可以完全独立于任何表格使用.然后在表单构造器中设置工作程序
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged +=
new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
并仅在按钮单击处理程序中执行此操作
backgroundWorker1.RunWorkerAsync();
对于在“组件”部分的工具箱中找到的大多数或所有组件,同样的考虑同样适用.