最近在学习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# 计时器
里面是使用线程来实现的,但是出现的情况是:毫秒的第一位是按照秒来变的(应该是十分之一秒),而“秒”那里是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# 计时器
Thread.Sleep(1);并不一定休眠1ms,可能大很多.
Timecount单位是ms,所以代码可改:
this.txtss.Text = (Timecount / 1000).ToString();
this.txtmss.Text = Timecount.ToString();
[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);
去掉赋值到文本框的时间浪费,这个精度是对的