在多线程中安全使用Timers

时间:2013-12-02 04:32:52

标签: c# multithreading

我必须启动计时器并在屏幕上显示,而我正在做其他事情,所以我决定在另一个线程中实现我的计时器这里是我的代码:

private void button1_Click(object sender, EventArgs e)
        {


            Thread th1 = new Thread(new ThreadStart(threadCall1));
            th1.IsBackground = true;
            th1.Start();

            secret = a.Next(0, 101);
            counter = 0;
            label2.Text = "";
            button1.Enabled = false;

        }

public void updatetimer()
        {
            Stopwatch aa = Stopwatch.StartNew();
            TimeSpan ts;
            while (true)
            {
                ts = aa.Elapsed;
                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}:{3:000}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
                label3.Text = elapsedTime;
            }
        }
        public delegate void threadJob();

        public void threadCall1()
        {
            Invoke(new threadJob(updatetimer));
        }

每当我运行并单击该按钮时,我的应用程序就会冻结响应任何其他操作?它有什么问题吗?

2 个答案:

答案 0 :(得分:1)

阅读文档。 Control.Invoke

  

在拥有控件底层窗口句柄的线程上执行指定的委托。

您正在新线程中调用Form的Invoke方法..这实际上毫无意义。

您应该将控制权限移至自己的功能,并使用Invoke仅调用该功能。将计算保留在线程中。

答案 1 :(得分:1)

尝试更像这样的事情:

    private bool Timing = false;

    private void button1_Click(object sender, EventArgs e)
    {
        Timing = true;
        Thread th1 = new Thread(updatetimer);
        th1.IsBackground = true;
        th1.Start();

        secret = a.Next(0, 101);
        counter = 0;
        label2.Text = "";
        button1.Enabled = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Timing = false;
        button1.Enabled = true;
    }

    public void updatetimer()
    {
        Stopwatch aa = Stopwatch.StartNew();
        TimeSpan ts;
        while (Timing)
        {
            ts = aa.Elapsed;
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}:{3:000}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
            this.Invoke((MethodInvoker)delegate
            {
                label3.Text = elapsedTime;
            });
            System.Threading.Thread.Sleep(50);
        }
    }