1

我有一个后台工作人员负责我的应用程序中的计时器。这是代码:

    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 方法,但未触发事件。有什么提示吗?

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

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

4 回答 4

3

Put a breakpoint, or a Debug.Print or System.Windows.Forms.Messagebox just before bgwTimer.ReportProgress(i), to verify that you're actually entering the while loop.

Note that the BackgroundWorker is not actually a timer; it's a wrapper for a thread that provides a threadsafe invoking layer for your user interface.

Your if (bgwTimer.CancellationPending) { } should be inside the while loop, not outside it. It will only get checked once in your current code.

Note that, if you're inside the DoWork event handler, then by definition you're running an asynchronous process, so IsBusy should always be true (according to the MSDN documentation), and therefore your while is an infinite loop. But check it with your debugger.

于 2012-10-16T14:47:49.407 回答
3

它不会引发事件,因为 的值i始终为零,这很有帮助,但我在不久前构建后台工作人员时发现了同样的事情。

于 2012-10-16T14:53:02.423 回答
2

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

   bgwTimer.RunWorkerAsync();
于 2012-10-16T14:56:00.347 回答
0

In the DoWork-Method replace bgwTimer through ((BackgroundWorker)sender). Maybe this is the problem

于 2012-10-16T14:48:33.067 回答