求一个WinForm 计时器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求一个WinForm 计时器相关的知识,希望对你有一定的参考价值。

一个label控件显示时间读数,一个按纽可以用回车或空格键控制,按第一次开始记时,再按停止记时,并把第一次的记时数据保存到一个文本文件里,再按读数清零开始记时,以此重复.我会追加重分的!!!!!

偶使用 VS2003 为你编写,已通过调试:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1

/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form

private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button1;

private bool isStart = false; // 记录是否启动
private int cnt; // 已经计时的次数
private DateTime beginTime; // 记录启动时的时间
const string FileName = "C:\\time.txt"; // 保存日志的文件名

private System.Windows.Forms.Timer timer1;
private System.ComponentModel.IContainer components;

public Form1()

//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//


/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )

if( disposing )

if (components != null)

components.Dispose();


base.Dispose( disposing );


#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()

this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 40);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(112, 24);
this.label1.TabIndex = 0;
this.label1.Text = "00:00:00.00";
//
// button1
//
this.button1.Location = new System.Drawing.Point(160, 40);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "启动";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// timer1
//
this.timer1.Interval = 50;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AcceptButton = this.button1;
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.button1);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);


#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()

Application.Run(new Form1());


private void Form1_Load(object sender, System.EventArgs e)

// 读取日志文件,初始化 cnt 计数器
try

// 读取日志文件,并使用操作系统默认的编码方案
System.IO.StreamReader sr = new System.IO.StreamReader(FileName, System.Text.Encoding.Default);

string line = sr.ReadToEnd();
sr.Close();

// 使用正则对像,分析日志,解析已经启动计时器的次数。
System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(line, "第\\s*(\\d+)");
if(matches.Count > 0)
this.cnt = int.Parse(matches[matches.Count - 1].Groups[1].Value);
else
this.cnt = 0;

catch

this.cnt = 0;



private void button1_Click(object sender, System.EventArgs e)

if(this.isStart) // 停止计时

this.timer1.Enabled = false;
this.timer1_Tick(this.timer1, e); // 停止计时后,最后一次计算时间,以保证计时正确(计时器设定为 50ms)。
System.IO.StreamWriter sw = new System.IO.StreamWriter(FileName, true, System.Text.Encoding.Default);

// 可以事先把字符串连接起来,再执行 Write 方法,但这样可以避免字符串连接运算(大文本时效率较高)。
sw.Write("第 ");
sw.Write((++this.cnt).ToString());
sw.Write(" 次计时:");
sw.Write(this.label1.Text);
sw.Write("\r\n");
sw.Close();

//this.label1.Text = "00:00:00.00";
this.button1.Text = "启动";

else // 开始计时

this.beginTime = DateTime.Now;
this.timer1.Enabled = true;
this.button1.Text = "停止";


this.isStart = !this.isStart;


private void timer1_Tick(object sender, System.EventArgs e)

TimeSpan ts = DateTime.Now - this.beginTime; // 使用当前时间减去启动时记录的时间
this.label1.Text = ts.Hours.ToString("d2") + ":" + ts.Minutes.ToString("d2") + ":" + ts.Seconds.ToString("d2") + "." + ts.Milliseconds.ToString("d2");


参考技术A Timer 控件

winform中多线程与定时器冲突

我在一个winform项目中同时使用了定时器与多线程。 程序不稳定,有时会弹出异常System.InvalidOperationException。 问题签名:
问题事件名称: CLR20r3
问题签名 01: bscanPlusV3_prepare.exe
问题签名 02: 1.0.0.0
问题签名 03: 59954209
问题签名 04: System.Drawing
问题签名 05: 4.6.1099.0
问题签名 06: 58d873ec
问题签名 07: 307
问题签名 08: 475
问题签名 09: System.InvalidOperationException
OS 版本: 6.1.7601.2.1.0.274.10

感觉像是多线程的使用不规范导致的线程死锁。 但是我的线程中的逻辑只是进行计算,并未操作控件,因此怀疑可能是定时器与多线程冲突导致的死锁。
调查发现timer控件引用的是System.Windows.Forms.Timer类,该类只适合于单线程的环境。 一个 Timer 用于在用户定义的时间间隔引发事件。 此 Windows 计时器专为使用 UI 线程来执行处理的单线程的环境。 它要求用户代码有一个可用的用户界面消息泵,并且始终在同一个线程操作或到另一个线程的调用封送。 https://msdn.microsoft.com/zh-cn/library/system.windows.forms.timer

这时候,需要用System.Windows.Forms.Timer命名空间下的Timer来替代原有的Timer。 VS2012中默认只有System.Windows.Forms.Timer控件,如果要使用System.Timers.Timer的控件需要在工具箱右键单击【选择项】在.NET Framework组件中选择System.Timers命名空间中的Timer控件。 https://msdn.microsoft.com/zh-cn/library/system.timers.timer.aspx

System.Timers.Timer控件的使用方法基本与System.Windows.Forms.Timer相同。问题得到了解决~

以上是关于求一个WinForm 计时器的主要内容,如果未能解决你的问题,请参考以下文章

winform 中如何获取计时器控件的值

winform 窗体加载时间过长 在load事件中,要初始化很多控制的数据源。导致页面显示出来很慢,求方法

C# winform 两个定时器访问同一个变量

我想使用计时器在winform中每1秒更改一次背景色

WinForm应用Timer定时器(基本)

毫秒级别计时器扩展----------WinForm控件开发系列