最近在学习C#,想做一个倒计时的小程序,但是使用Timer来完成,计时总是不太准确,我在晚上看到了这个帖子http://www.cnblogs.com/yinluhui0229/archive/2012/08/20/2648313.html
里面是使用线程来实现的,但是出现的情况是:毫秒的第一位是按照秒来变的(应该是十分之一秒),而“秒”那里是10秒跳一次,请问一下这是为什么?
Timecount 是总毫秒数 每次-1
Timecount -= 1;
线程挂起时间为1毫秒
Thread.Sleep(1);我把这个程序上传了,如果看不懂我的描述的话,可以运行一下代码就看出来了。
http://download.csdn.net/detail/openzpc/5410551谢谢!!!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace TimeThread
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        int Timecount = 0;//记录倒计时总毫秒数
        int isstop = 0;//标示是否启动/暂停的变量,0表示第一次初始化
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.button1.Text == "开始计时" || this.button1.Text == "继续计时")
            {
                this.button1.Text = "暂停计时";
                if (isstop == 0)//第一次执行或者倒计时事件设置发生变化,则重新倒计时
                {
                    Timecount = Convert.ToInt32(txtTotalmm.Text) * 60000;//毫秒
                    Thread counter = new Thread(Counter);
                    counter.Start();
                    Control.CheckForIllegalCrossThreadCalls = false;//放弃捕获对错误线程的调用,否则在线程中无法调用控件名  
                    this.txtTotalmm.ReadOnly = true;
                    txthour.ForeColor = Color.Black;
                    txtmm.ForeColor = Color.Black;
                    txtss.ForeColor = Color.Black;
                    txtmss.ForeColor = Color.Black;
                }
                isstop = 1;//启动
            }
            else
            {
                this.button1.Text = "继续计时";
                //this.timer1.Stop();
                isstop = 2;//暂停
            }
        }
        public void Counter()
        {
            try
            {
                while (Timecount >= 0)
                {
                    this.txthour.Text = (Timecount / 3600000).ToString();
                    this.txtmm.Text = ((Timecount / 60000) % 60).ToString();
                    this.txtss.Text = ((Timecount / 1000) % 60).ToString();
                    this.txtmss.Text = (Timecount % 1000).ToString();
                    if (Timecount == 0)
                    {
                        txthour.ForeColor = Color.Red;
                        txtmm.ForeColor = Color.Red;
                        txtss.ForeColor = Color.Red;
                        txtmss.ForeColor = Color.Red;
                        this.txtTotalmm.ReadOnly = false;
                        this.button1.Text = "开始计时";
                        isstop = 0;
                        try
                        {
                            Thread currthread = Thread.CurrentThread;
                            currthread.Abort();// 终止当前进程,会触发ThreadAbortException异常,从而终止进程,所以下面需要捕获该异常才能终止进程
                        }
                        catch (ThreadAbortException) { }
                    }
                    if (isstop != 2)
                        Timecount -= 1;
                    Thread.Sleep(1);
                }
            }
            catch { }//处理异常关闭情况下的异常问题
        }    }
}
多线程C# 计时器 

解决方案 »

  1.   

    只是运行了线程,没有用计时器,可以用System.Threading.Timer,大概精度有20多ms,或者用api,精度更高.
    Thread.Sleep(1);并不一定休眠1ms,可能大很多.
    Timecount单位是ms,所以代码可改:
      this.txtss.Text = (Timecount / 1000).ToString();
      this.txtmss.Text = Timecount.ToString();
      

  2.   

             //调用API函数
            [DllImport("kernel32.dll")]
            extern static short QueryPerformanceCounter(ref long x);
            [DllImport("kernel32.dll")]
            extern static short QueryPerformanceFrequency(ref long x);
            //定义延迟函数
            public void delay(long delay_Time)
            {
                long stop_Value = 0;
                long start_Value = 0;
                long freq = 0;
                long n = 0;            QueryPerformanceFrequency(ref freq);  //获取CPU频率
                long count = delay_Time * freq / 1000;
                QueryPerformanceCounter(ref start_Value); //获取初始前值            while (n < count) //不能精确判定
                {
                    QueryPerformanceCounter(ref stop_Value);//获取终止变量值
                    n = stop_Value - start_Value;
                }
            }        Timecount -= 1;
            delay(1);
    去掉赋值到文本框的时间浪费,这个精度是对的