如何停止按钮点击影响的计时器?

时间:2014-02-27 10:28:57

标签: c# winforms

我正在开发一个winform应用程序,其中我有一个timer.it用于在表单上显示秒表。当我按下按钮时,我的计时器被打断了。我希望我的计时器在按下单击按钮时不会中断。我的代码如下: -

private void button1_Click(object sender, EventArgs e)
{
    if (!_timerRunning)
    {
        // Set the start time to Now
        _startTime = DateTime.Now;

        // Store the total elapsed time so far
        _totalElapsedTime = _currentElapsedTime;

        _timer.Start();
        _timerRunning = true;
    }
    SqlConnection Con = new SqlConnection("Data Source=69.162.83.242,1232;Initial Catalog=test1;Uid=test;pwd=1234@Test;MultipleActiveResultSets=true;Connect TimeOut=60000;");
    //SqlConnection Con = new SqlConnection("Data Source=ADMIN-PC\\YASH;Initial Catalog=test;Integrated Security=True; Connect TimeOut=600");
    Con.Open();
    string messageMask = "{0} @ {1} : {2}";
    string message = string.Format(messageMask, label6.Text, DateTime.Now.ToShortTimeString(), richTextBox2.Text);
    richTextBox1.AppendText(Environment.NewLine + message);
    SqlCommand cmd, cmd1;
    cmd = new SqlCommand("Update Chat set UserInitial=@message,Updated=1 where ExpertName ='" + label6.Text + "'", Con);
    cmd.Parameters.AddWithValue("@message", message);
    cmd.ExecuteNonQuery();
    Con.Close();
    richTextBox2.Text = String.Empty;
    richTextBox1.ScrollToCaret();
}

private void timer1_Tick(object sender, EventArgs e)
{
    richTextBox1.ScrollToCaret();
    count = count + 1;
    count1 = count1 + 1;
    timerSinceStartTime = new TimeSpan(timerSinceStartTime.Hours, timerSinceStartTime.Minutes, timerSinceStartTime.Seconds + 1);
    // The current elapsed time is the time since the start button was
    // clicked, plus the total time elapsed since the last reset
    _currentElapsedTime = timerSinceStartTime + _totalElapsedTime;

    // These are just two Label controls which display the current 
    // elapsed time and total elapsed time

    if (count1 == 180)
    {
        MessageBox.Show("You are Automaticlly hired by User");
        if (label7.Visible == true)
        {
            label7.Visible = false;
            count = 0;
            timerSinceStartTime = new TimeSpan(00, 00, 00);
            label3.Visible = true;
        }
    }
    label3.Text = timerSinceStartTime.ToString();


    // If we're running on the UI thread, we'll get here, and can safely update 
    // the label's text.


    richTextBox1.ScrollToCaret();
}

如何解决? 在此先感谢

2 个答案:

答案 0 :(得分:1)

您的问题源于您使用的System.Windows.Forms.Timer没有线程且依赖于消息泵的事实。当您的程序忙于UI线程时,将不会处理消息泵。

您可以通过转移到支持线程的计时器来改进这一点。我更喜欢System.Timers.Timer,但也有System.Threading.Timer

使用System.Timers.Timer如果您没有传递任何同步对象,则会在后台线程上引发tick事件,以便在单独的线程中处理事件处理程序中的任何代码。

当然,要更新表单我们必须编组回UI线程,因此我们还需要使用Control.Invoke()

这非常粗糙,但是像这样:

System.Timers.Timer timer = new System.Timers.Timer();  

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = 1000;
timer.AutoReset = false;
timer.Enabled = true;

public void OnTimer(object sender, ElapsedEventArgs e)
{
    // Do something busy like dancing

    // Update form
    Invoke((MethodInvoker)delegate() {
        UpdateForm();
    });

    // Restart timer
    ((System.Timers.Timer)sender).Start();
}

public void UpdateForm()
{
   // Code to update the form
}

注意我使用AutoReset = false,这样如果tick事件花费的时间超过了计时器间隔,则不会重叠。您可能会或可能不会想要这完全取决于您正在做什么。

答案 1 :(得分:0)

你可以试试这个,

private bool bStopTimer = true;
private void StartTimer()
{
    System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ThreadTimer));
    thread.IsBackground = true;
    thread.Start();
}


private void ThreadTimer()
{
    while (bStopTimer)
    {
        System.Threading.Thread.Sleep(1000); //interval in millisecond
        lock(lblLabel.Text)
        {
            lblLable.Text = System.DateTime.Now.ToString("HH:mm:ss");
        }
    }
}

<强>更新

将此行放在Application.Run(new frmForm);

之前
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;