首页
>
软件编程
>
C#教程
> c# 线程定时器 System.Threading.Timer
c# 线程定时器 System.Threading.Timer的使用
2023-02-06 11:09:28
作者:驰愿
本文主要介绍了c# 线程定时器 System.Threading.Timer的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
System.Threading.Timer 是由线程池调用的。
所有的Timer对象只使用了一个线程来管理。这个线程知道下一个Timer对象在什么时候到期。下一个Timer对象到期时,线程就会唤醒,在内部调用ThreadPool 的 QueueUserWorkItem,将一个工作项添加到线程池队列中,使你的回调方法得到调用。如果回调方法的执行时间很长,计时器可能(在上个回调还没有完成的时候)再次触发。这可能造成多个线程池线程同时执行你的回调方法。
callback : 一个Object 类型参数的委托,周期调用的函数。
state: callback 委托调用时的参数。
dueTime: 定时器延时多久开始调用。单位 毫秒
period: 定时器每隔多久调用一次。单位 毫秒
不能使用局部变量来创建指向一个线程定时器。因为局部变量会被GC回收,导致定时器失效。
比如下面的例子:
static void Main(string[] args) {
Run();
//为了加快GC垃圾回收,不停的创建对象
for (int i = 0; i < 10000; i++) {
cc tmp = new cc();
Thread.Sleep(10);
Console.ReadKey();
static int id;
static void Run() {
Timer timer = new Timer(DoTime, null, 500, 500);
static void DoTime(object obj) {
Console.WriteLine(id++);
class cc{
public int[] a = new int[1000];
定时器执行4次后停止了。定时器什么时候停止取决于GC什么时候回收。如果一直没有GC的回收,那么将会一直执行下去。比如把上方创建 cc 对象的代码删除。定时器将会一直执行。
可以在Main方法中使局部变量 或者 使用全局变量来存放Timer 对象 避免 clr 把Timer 回收。
比如改成这样
static Timer timer;
static void Main(string[] args) {
timer = new Timer(DoTime, null, 500, 500);
//为了加开GC垃圾回收,不停的创建对象
for (int i = 0; i < 10000; i++) {
cc tmp = new cc();
Thread.Sleep(10);
Console.ReadKey();
static int id;
static void DoTime(object obj) {
Console.WriteLine(id++);
如果回调方法的执行时间很长,计时器可能(在上个回调还没有完成的时候)再次触发。这可能造成多个线程池线程同时执行你的回调方法。
static Timer timer1;
static void Main(string[] args) {
timer1 = new Timer(DoTime, 1, 500, 500);
Console.ReadKey();
static int id;
static void DoTime(object obj) {
int idx = id ++;
Console.WriteLine("处理开始:" + idx + "," + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1200);
Console.WriteLine("处理完毕:" + idx + "," + Thread.CurrentThread.ManagedThreadId);
定时器第一次任务还没执行完毕,第二次,第三次回调就开始了。多个线程同时并发 DoTime 方法
period 使用 Timeout.Infinite。这个参数将导致DoTime 只处理一次。 在回调方法中使用 Change方法来修改 dueTime,period 参数。period 继续使用 Timeout.Infinite. 使用这个方法要注意如果timer 在被Dispose了,使用Change 将会引发异常。 比如
static Timer timer1;
static void Main(string[] args) {
timer1 = new Timer(DoTime, 1, 0, Timeout.Infinite);
Console.ReadKey();
static int id;
static void DoTime(object obj) {
int idx = id ++;
Console.WriteLine("处理开始:" + idx + "," + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1200);
Console.WriteLine("处理完毕:" + idx + "," + Thread.CurrentThread.ManagedThreadId);
timer1.Change(500,Timeout.Infinite);
使用Disponse停止定时器 如果Timer 不会再使用 则可以 使用 Dispose 方法来停止定时器。 如果定时器运行到中途。使用Dispose方法后,callback还是会执行完一个完整的生命周期,不会中途停止。并且Dispose方法不会等待 callback的这次调用完成。只是定时器下次不再调用 callback。
使用Change停止定时器 把 dueTime 参数置为-1就可以停止定时器。同样的,它不会中断在运行中的callback,只是下一次不再回调。 这个方法停止的定时器 还可以使用Change 再次利用定时器。
到此这篇关于c# 线程定时器 System.Threading.Timer的使用的文章就介绍到这了,更多相关c# 线程定时器 System.Threading.Timer内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
C#调用js库的方法示例代码 2023-01-01
C#中使用Spire.doc对word的操作方式 2023-01-01
使用C#连接SQL Server的详细图文教程 2023-02-02
Linq利用Distinct去除重复项问题(可自己指定) 2023-01-01
c# 线程定时器 System.Threading.Ti 2023-01-01
C#中括号强转、as、is区别详解 2023-01-01
C#中将dateTimePicker初始值设置为空 2023-01-01
关于C#中的Invoke示例详解 2023-01-01
美国设下计谋,用娘炮文化重塑日本,已影响至中国 2021-11-19 时空伴随者是什么意思?时空伴随者介绍 2021-11-09 工信部称网盘企业免费用户最低速率应满足基本下载需求,天翼云盘回应:坚决支持,始终 2021-11-05 2022年放假安排出炉:五一连休5天 2022年所有节日一览表 2021-10-26
电脑版 - 返回首页
2006-2023 脚本之家 JB51.Net , All Rights Reserved. 苏ICP备14036222号