问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

c#计时器用法

发布网友 发布时间:2022-04-23 13:56

我来回答

4个回答

热心网友 时间:2022-04-23 15:26

c#中提供了三种类型的计时器:
1、基于 Windows 的标准计时器(System.Windows.Forms.Timer)
2、基于服务器的计时器(System.Timers.Timer)
3、线程计时器(System.Threading.Timer)
下面我就通过一些小实验来具体分析三种计时器使用上面的异同点,特别是和线程有关的部分。
实验例子截图:

一、基于 Windows 的标准计时器(System.Windows.Forms.Timer)
首先注意一点就是:Windows 计时器是为单线程环境设计的
此计时器从Visual Basic 1.0 版起就存在于该产品中,并且基本上未做改动
这个计时器是使用最简单的一种,只要把工具箱中的Timer控件拖到窗体上,然后设置一下事件和间隔时间等属性就可以了

实验出来的结果也完全符合单线程的特点:
1、当启动此计时器后,会在下方子线程ID列表中显示子线程ID,并且和主线程ID相同
private void formsTimer_Tick(object sender, EventArgs e)
{
i++;
lblSubThread.Text += "子线程执行,线程ID:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
}

2、当单击主线程暂停5秒后,子线程会暂停执行,并且当5秒之后不会执行之前被暂停的子线程,而是直接执行后面的子线程(也就是会少输出几行值)
System.Threading.Thread.Sleep(5000);
3、在子进程的事件中暂停5秒会导致主窗口相应无响应5秒
4、定义一个线程静态变量:
[ThreadStatic]
private static int i = 0;
在子线程事件中每次加一,再点击线程静态变量值会得到增加后的i值

二、基于服务器的计时器(System.Timers.Timer)
System.Timers.Timer不依赖窗体,是从线程池唤醒线程,是传统的计时器为了在服务器环境上运行而优化后的更新版本
在VS2005的工具箱中没有提供现成的控件,需要手工编码使用此计时器
使用方式有两种,
1、通过SynchronizingObject属性依附于窗体

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

timersTimer.Enabled = false;
timersTimer.Interval = 100;
timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(timersTimer_Elapsed);

timersTimer.SynchronizingObject = this;

通过这种方式来使用,实验效果几乎和基于 Windows 的标准计时器一样,只是在上面的第二条实验中,虽然也会暂停子线程的执行,不过在5秒之后把之前排队的任务都执行掉(也就是不会少输出几行值)
2、不使用SynchronizingObject属性
这种方式就是多线程的方式了,即启动的子线程和主窗体不在一个线程。不过这样也存在一个问题:由于子线程是单独的一个线程,那么就不能访问住窗体中的控件了,只能通过代理的方式来访问:

delegate void SetTextCallback(string text);
.
.
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//使用代理
string text = "子线程执行,线程ID:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
i++;
}

private void SetText(string text)
{
lblSubThread.Text += text;
}
这样我们再次实验就会得到如下的结果:
1、当启动此计时器后,会在下方子线程ID列表中显示子线程ID,并且和主线程ID不相同

2、当单击主线程暂停5秒后,子线程会一直往下执行(界面上可能看不出来,不过通过在子线程输出文件的方式可以很方便的看出来)
3、在子进程的事件中暂停5秒不会导致主窗口无响应
4、在子线程事件中每次给线程静态变量加一,再点击线程静态变量值得到的值还是0(不会改变主窗口中的线程静态变量)
三、线程计时器(System.Threading.Timer)
线程计时器也不依赖窗体,是一种简单的、轻量级计时器,它使用回调方法而不是使用事件,并由线程池线程提供支持。
对消息不在线程上发送的方案中,线程计时器是非常有用的。
使用方法如下:

System.Threading.Timer threadTimer;
public void ThreadMethod(Object state)
{
//使用代理
string text = "子线程执行,线程ID:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
i++;
}

private void Form1_Load(object sender, EventArgs e)
{
threadTimer = new System.Threading.Timer(new System.Threading.TimerCallback(ThreadMethod), null, -1, -1);
}

暂停代码:
threadTimer.Change(-1, -1);

实验的效果和基于服务器的计时器(System.Timers.Timer)的第二种方式是一样的,
当然具体的使用方法和原理是不一样的,最主要的就是这种方式使用的是代理的方式而不是事件的方式,并且可以不依赖于窗体和组件而单独执行

下面列出老外总结的一张表(三种方式的区别):
Feature descriptionSystem.Timers.TimerSystem.Threading.TimerSystem.Windows.Forms.Timer
Support for adding and removing listeners after the timer is instantiated.YesNoYes
Supports call backs on the user-interface threadYesNoYes
Calls back from threads obtained from the thread poolYesYesNo
Supports drag-and-drop in the Windows Forms DesignerYesNoYes
Suitable for running in a server multi-threaded environmentYesYesNo
Includes support for passing arbitrary state from the timer initialization to the callback.NoYesNo
Implements IDisposableYesYesYes
Supports one-off callbacks as well as periodic repeating callbacksYesYesYes
Accessible across application domain boundariesYesYesYes
Supports IComponent – hostable in an IContainerYesNoYes

原文来自网络

热心网友 时间:2022-04-23 16:44

定时器精确度很低的,大约55ms,如果想精确计时,就在开始时获得一个时间,结束时获得一个时间,用DateTime.Now.Ticks获得时间,两个相减即可。追问和楼下一样给个完整代码吧。
用DateTime.Now.Ticks获得时间的单位是什么?

追答// 开始计时
            long st = DateTime.Now.Ticks;
            // 写耗时代码吧
            // 结束计时,计算耗时
            long et = DateTime.Now.Ticks;
            long ct = et - st;
            TimeSpan ts = new TimeSpan(ct);
            MessageBox.Show(string.Format("总共消耗: {0}毫秒", ts.TotalMilliseconds));

热心网友 时间:2022-04-23 18:18

用System.Windows.Forms.Timer
每1毫秒调用一次Timer的Tick事件来计时。
当你执行1万次for循环后调用Timer.Stop()停止计时器就行了

热心网友 时间:2022-04-23 20:10

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
namespace RateDemo
{
class Program
{
static int countTime ;
static void Main(string[] args)
{
Timer time = new Timer();

bool flag = true;
time.Interval = 1;//设置timer时间间隔为1毫秒
time.Elapsed+=new ElapsedEventHandler(time_Elapsed);
for (int i = 0; i < 10000000; i++)
{
if (flag)
{
time.Start();
flag = false;
}
//时间和你在这里做的事情有关系
}
Console.WriteLine(countTime);
time.Stop();
Console.Read();
}
static void time_Elapsed(object sender, ElapsedEventArgs e)
{
countTime++;
}
}
}追问非常感谢!

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
找几本一流的小说。类型' 完结什么的无所谓. 不要幼稚就好 沈阳职高学校排名 沈阳哪个公办职高和中专好 沈阳有哪些职高学校比较好? gpw一代和二代的区别有哪些 罗技gpw一代和二代区别介绍 第一代和第二代的区别 gpw二代和一代有什么区别 二代和一代区别详情分享 设张举措的意思设张举措的解释设张举措接龙 设张的成语设张的成语是什么 人字地砖铺法怎么找平方 在金坷垃广告中,对金坷垃原理的解释有什么问题吗?拜托各位了 3Q 金坷垃广告演员去哪了 金坷垃化肥广告 哪个公司拍的 access2010数据库中,VBA编程,“本月最后一天”的表达式??? 金坷垃这样的广告视频版权归属哪方?对金坷垃进行鬼畜剪辑需要获得广告制作者的授权吗? 金坷垃广告为什么是美日非组合 求金坷垃原版广告叫什么,就是三个人在车前的那个,告诉我名字 金坷垃广告的真实性如何。请详细说明哪些是虚假宣传? 金坷垃的广告做的到底是成功还是失败 金坷拉是什么意思? 金坷垃的广告做的到底是成功还是失败? 金坷垃广告的最后一句是“阿妹你看,狗狗压上帝”吗? 请懂EXCEL和ACCESS两个软件的VBA编程的高手进!!高分悬赏!! 吃什么能让头发黑起来 金坷垃是代表屎吗 做仰卧起坐是连续做做五十个吗??还是做了十个休息一两分钟,继续做五组!这样有效果吗 想头发黑吃什么效果好 仰卧起坐不连续长久的做的话 是不是会起反作用啊?怎么越减越肥啊? 仰卧起坐 要是能连续做100-120下 算怎么样呢 金坷垃的经典广告内容 黄鳝煮汤用什么搭配? 黄鳝用什么材料煲汤? 笑字的笔画顺序 老松下空调没有标志不知道加什么氨,加氨头是公制的? 汉字笑的合成部件 古代字笑.弯 黄鳝用什么熬汤? 用自己的话说说中国文字笑字中包含了哪些信息 表示三个字笑的词语有哪些成语大全 第一字笑的成语 做手游主播要怎样才能赚到钱呢?像大神tv或触手tv这类平台的? 夏天开空调调到26度,刚打开时吹热风,然后才吹冷风,是哪里坏了吗? 夏天空调吹久了有什么坏处? 只寻花柳七字笑是什么意思 内话字笑以,词剧搞100人美串睡 文字笑解 微信各字笑到痴傻什么意思 天字话字伦字笑字加什字能组成一起 带有“笑”字的四字搞笑贬义成语,越多越好…越快越好…谢谢 天字笑字话字伦字中间加一个什么能让这四个字组合起来