System.Threading.Timer
System.Threading.Timer是使用多线程时间定时类:
调用方法:
Timer(TimerCallback callback, object? state, int dueTime, int period);
参数有4个:
TimerCallback
是委托类型方法,我们只需new TimerCallback(定时运行的方法名)就可以了;
state
是回调函数的参数,可以传null;
dueTime
是触发回调函数等待的时间间隔,如果为0则不等待;
period
是回调函数再次被触发的时间间隔;
dueTime
和 period
是否觉得很茫然?怎么定义两个时间间隔参数呢? 其实System.Threading.Timer是多线程触发回调函数的,也就是说第一次触发的事件不会影响下一次运行回调函数的时间。像车站,1号车在等待dueTime
时间后发车,并承诺一定的时间后到站, 2号车将在1号车出发后period
的时间发车,3号车也将在2号车出发后period
的时间发车,也就是说就算1号车还未到目的地站点也会不断发车,如果1号车最后到了目的站点然后返回出发站点就可以再次被安排第二次发车了。线程就相当于车,车站就相当于System.Threading.Timer这个实例化的类。
using System;
using System.Diagnostics;
using System.Threading;
namespace TimerUse
{
class Program
{
// 定义时间对象,就是上面说的车站
static Timer timer = null;
// 定义定时运行的方法,就是上面说的车
static void TickTimer(object state)
{
string ThreadNo = Thread.CurrentThread.ManagedThreadId.ToString();
Debug.WriteLine("本车车号是:" + ThreadNo + " 出发时间为:" + DateTime.Now.ToString());
// 跑完全程需要4秒钟时间
Thread.Sleep(4000);
Debug.WriteLine("本车车号是:" + ThreadNo + " 到达目的地站并返回时间为:" + DateTime.Now.ToString());
}
static void TickTimerWithParameter(object state)
{
package package = (package) state;
Debug.WriteLine(package.ToString());
string ThreadNo = Thread.CurrentThread.ManagedThreadId.ToString();
Debug.WriteLine("本车车号是:" + ThreadNo + " 出发时间为:" + DateTime.Now.ToString());
// 跑完全程需要4秒钟时间
Thread.Sleep(4000);
Debug.WriteLine("本车车号是:" + ThreadNo + " 到达目的地站并返回时间为:" + DateTime.Now.ToString());
}
static void Main(string[] args)
{
// 实例化一个车站,定义发车指令规则,此处是: 车的类型是 TickTimer 这种功能的车,此类车不运载其他行李,发车规则是当车就绪先等待1秒钟,然后发车,下一辆车需等待上一辆车发车2秒后再出发
// timer = new Timer(new TimerCallback(TickTimer), null, 1000, 2000);
timer = new Timer(new TimerCallback(TickTimerWithParameter), new package { packageNo = 1001, weight = 10.22m, ownerName = "Li Sa"}, 1000, 2000);
Console.ReadLine();
}
// 向车站发出暂停发车的指令
static void Stop()
{
// Timeout.Infinite 代表无限等待
timer.Change(Timeout.Infinite, Timeout.Infinite);
}
// 再次向车站发出发车指令
static void Start()
{
// 设置车站发车指令需要按照 每辆就绪的车需等待1秒之后发车,下一辆车需上一辆车出发2秒后再发车
timer.Change(1000, 2000);
}
public class package
{
public int packageNo { get; set; }
public decimal weight { get; set; }
public string ownerName { get; set; }
public override string ToString()
{
return "本行李编号是" + packageNo + ",属于" + ownerName + "的, 重量为" + weight + "千克";
}
}
}
}
运行结果如下:
这里有个缺点,行李都是一个相同人的,能不能是动态的,也就是能不能载其他人的行李呢?这里可以的,就是再创建一个车站,如何?呵呵
你们开车开过瘾了没?