2

这是我迄今为止尝试过的:

  1. 放入button.Visible = false我的表单的初始化程序并放入button.Visible = true我的 backgroundWorkers 的 DoWork 事件的末尾。
    这会导致程序在 BackgroundWorker 完成工作后冻结。
    我不明白为什么。

  2. 放入button.Visible = false我的表单的初始化程序并button.Visible = true在我backgroundWorker1.RunWorkerAsync()调用之后放入。
    这不能正常工作,因为它在 BackgroundWorker 开始工作后立即显示按钮。
    我明白为什么会这样。

  3. button.Visible = falseanddoneEvent = new AutoResetEvent(false)放入表单的初始化程序中,然后在我的调用之后放入doneEvent.WaitOne()and 。 这样,除了我在表单中的 ProgressBar 停止正常工作(在所有工作完成之前它不会显示进度)之外,一切正常。 我可能对为什么会发生这种情况有一个直观的想法,但我并不真正理解它,也不知道如何解决它。 button.Visible = truebackgroundWorker1.RunWorkerAsync()

4

1 回答 1

5

当您的代码在 DoWork 事件中运行时,您不应在按钮上调用任何方法/属性,因为此代码与创建按钮的线程位于不同的线程中。BackgroundWorkwer
使用一组定义明确 的事件来处理您需要更新界面的情况,并且您应该将这些事件用于该任务。

例如,您可以将该属性设置WorkerReportsProgress为 true,订阅该事件ProgressChangedbackgroundWorker1.ReportProgress(...);在 DoWork 事件中调用以在您的后台工作进行时更新您的界面。

在您的情况下,您可能需要订阅该事件RunWorkerCompleted并在该事件中显示您的按钮

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (!e.Cancelled && e.Error == null)
    {
        button.Visible = true; 
    }
}

在 BackgroundWorker 的 MSDN 页面的链接中,有一个示例演示了如何在 DoWork 事件运行复杂任务时更新进度条。

于 2012-12-08T16:14:46.530 回答