分别用Invoke与BackgroundWorker实现计时器

在学习.NET多线程操作的过程中,有了这个小的示例程序。

Timer

它们都使用了System.Timers.Timer作为计时器,只是在更新UI时分别使用了传统的Invoke方式与.NET 4.0后引入的BackgroundWorker。从个人感受而言,前者少许多编码,后者从逻辑上更易理解。

源代码下载(7zip压缩)


一、传统Invoke方式

#region implementation by Invoke()
private System.Timers.Timer _timer = new System.Timers.Timer(1000);
private bool IsInvokeRunning = false;
private int _secondsOfInvoke = 0;

private void InitializeTimer()
{
    _timer.AutoReset = true;
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(
        (ts, te) =>
        {
            _secondsOfInvoke++;
            string message = new TimeSpan(0, 0, _secondsOfInvoke).ToString(@"mm\:ss");
            SetLabelText(message);
        }
    );
}

private void btnBegin_Click(object sender, EventArgs e)
{
    if (IsInvokeRunning)
    {
        IsInvokeRunning = false;
        _timer.Stop();

        string message = string.Format("{0} past.", new TimeSpan(0, 0, _secondsOfInvoke).ToString(@"mm\:ss"));
        MessageBox.Show(message);

        this.btnBegin.Text = "Begin";
        _secondsOfInvoke = 0;
        this.labelInvokeTime.Text = "00:00";
    }
    else
    {
        IsInvokeRunning = true;

        _timer.Start();
        this.btnBegin.Text = "Cancel";
    }
}

private delegate void SetLabelTextHandler(string text);
private void SetLabelText(string text)
{
    if (this.labelInvokeTime.InvokeRequired)
    {
        SetLabelTextHandler handler = new SetLabelTextHandler(SetLabelText);
        this.Invoke(handler, new object[] { text });
    }
    else
        this.labelInvokeTime.Text = text;
}
#endregion

二、BackgroundWorker方式

#region implementation by BackgroundWorker
private BackgroundWorker _worker = new BackgroundWorker() { WorkerSupportsCancellation = true, WorkerReportsProgress = true };
private bool IsWorkerRunning = false;
private int _secondsOfWorker = 0;

private void InitializeWorker()
{
    _worker.DoWork += new DoWorkEventHandler(
                    (s, e) =>
                    {
                        System.Timers.Timer timer = new System.Timers.Timer(1000);
                        timer.AutoReset = true;
                        timer.Elapsed += new System.Timers.ElapsedEventHandler(
                            (ts, te) =>
                            {
                                _secondsOfWorker++;
                                _worker.ReportProgress(0);
                            });

                        timer.Start();

                        while (true)
                        {
                            if (_worker.CancellationPending)
                            {
                                e.Cancel = true;
                                timer.Stop();
                                return;
                            }
                        }
                    });

    _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        (s, e) =>
        {
            if (e.Cancelled)
            {
                IsWorkerRunning = false;
                this.btnStart.Text = "Start";
            }

            string message = string.Format("{0} past.", new TimeSpan(0, 0, _secondsOfWorker).ToString(@"mm\:ss"));
            MessageBox.Show(message);

            _secondsOfWorker = 0;
            this.labelWorkerTime.Text = "00:00";
        });

    _worker.ProgressChanged += new ProgressChangedEventHandler(
        (s, e) =>
        {
            string message = new TimeSpan(0, 0, _secondsOfWorker).ToString(@"mm\:ss");
            this.labelWorkerTime.Text = message;
        });
}

private void btnStart_Click(object sender, EventArgs e)
{
    if (IsWorkerRunning)
    {
        IsWorkerRunning = false;
        this.btnStart.Text = "Start";

        _worker.CancelAsync();
    }
    else
    {
        IsWorkerRunning = true;
        this.btnStart.Text = "Stop";

        _worker.RunWorkerAsync();
    }
}
#endregion
转载请注明出处及作者,谢谢!
原文地址:https://www.cnblogs.com/Abbey/p/2174652.html