Backgroundworker ReportProgress事件不会触发

时间:2012-10-16 14:42:26

标签: c# multithreading timer progress-bar backgroundworker

我有一个背景工作者在我的应用程序中处理计时器。这是代码:

    protected override void OnLoad(EventArgs e)
    {
        // Inizializzo il backgroundworker 
        bgwTimer.WorkerReportsProgress = true;
        bgwTimer.WorkerSupportsCancellation = true;
        bgwTimer.DoWork += (bgwTimer_DoWork);
        bgwTimer.RunWorkerCompleted +=(bgwTimer_RunWorkerCompleted);
        bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged);
    }

    void bgwTimer_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        throw new NotImplementedException();
    }

    void bgwTimer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        throw new NotImplementedException();
    }

基本上,事件“ProgressChanged”永远不会被触发,因此我无法更新进度条的状态。 事件DoWork与此方法相关联:

    void bgwTimer_DoWork(object sender, DoWorkEventArgs e)
    {
        int i = 0;
        if (bgwTimer.CancellationPending)
        {
            e.Cancel = true;
        }
        else
        {
            while (bgwTimer.IsBusy)
            {                
                Thread.Sleep(1000);
                bgwTimer.ReportProgress(i);
                refreshTimer();
            }
        }
    }

在我身边代码看起来不错,运行正常。如您所见,调用了ReportProgress方法,但未触发该事件。任何提示?

更新: Whops!我发现事件“bgwTimer_ProgressChanged”只有在事件声明后立即运行RunWorkerAsync时才会被触发。基本上是:

bgwTimer.ProgressChanged + =(bgwTimer_ProgressChanged); bgwTimer.RunWorkerAsync(); //这有用!

由于我在用户按下按钮时运行工作程序,因此不会触发事件。


以下是点击事件按钮的代码:

    private void btnNext_Click(object sender, EventArgs e)
    {            
        this.TopMost = true;
        btnNext.Enabled = false;
        progressBar1.Step = 0;

        if (_bgwTimer.IsBusy)
            _bgwTimer.CancelAsync();
        else
            _bgwTimer.RunWorkerAsync();
    }

4 个答案:

答案 0 :(得分:3)

Debug.Print之前设置断点或System.Windows.Forms.MessageboxbgwTimer.ReportProgress(i),以确认您实际上是在进入while循环。

请注意,BackgroundWorker实际上不是计时器;它是一个线程的包装器,为您的用户界面提供线程安全的调用层。

您的if (bgwTimer.CancellationPending) { }应位于while循环内,而不在其外部。它只会在您当前的代码中检查一次。

请注意,如果您在DoWork事件处理程序中,那么根据定义,您正在运行异步进程,因此IsBusy应始终为true(根据MSDN文档),并且因此你的while是一个无限循环。但请使用调试器进行检查。

答案 1 :(得分:3)

它没有引发事件,因为i的值总是为零,这有助于没有记录,但我在一段时间后构建后台工作者时发现了同样的事情。

答案 2 :(得分:2)

你忘了启动工人。将此行添加到OnLoad()方法:

   bgwTimer.RunWorkerAsync();

答案 3 :(得分:0)

在DoWork-Method中,通过((BackgroundWorker)sender)替换bgwTimer。也许这就是问题