闽公网安备 35020302035485号
System.Windows.Forms.Timer System.Windows.Threading.DispatcherTimer System.Web.UI.Timer通常情况下,WinForm、WPF中的定时器是在UI线程上执行回调函数,因此可以直接访问UI元素。由于WinForm、WPF支持单线程单元模型(Single-Thread Apartment,STA),定时器间隔事件是在UI线程上触发,因此,不用担心线程安全问题。System.Web.UI.Timer是通过Javascript定时器和服务端异步回调实现,也是单线程的。
public partial class TimerFrom : Form
{
private System.Windows.Forms.Timer digitalClock;
private void TimerFrom_Load(object sender, EventArgs e)
{
digitalClock = new System.Windows.Forms.Timer();//创建定时器
digitalClock.Tick += new EventHandler(HandleTime);//注册定时任务事件
digitalClock.Interval = 1000;//设置时间间隔
digitalClock.Enabled = true; // 堆代码 duidaima.com
digitalClock.Start(); //开启定时器
}
public void HandleTime(Object myObject, EventArgs myEventArgs)
{
labelClock.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
private void frmTimerDemo_FormClosed(object sender, FormClosedEventArgs e)
{
digitalClock.Stop();//停止定时器
digitalClock.Dispose();
}
}
System.Windows.Threading.DispatcherTimerprivate void Dt_Tick(object sender, EventArgs e)
{
Dispatcher.BeginInvoke((Action)delegate ()
{
text1.Text = DateTime.Now.ToString();
});
Console.WriteLine(DateTime.Now.ToString());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>{
DispatcherTimer dt = new DispatcherTimer();
dt.Tick += Dt_Tick;
dt.Interval = TimeSpan.FromSeconds(1);
dt.Start();
Dispatcher.Run();
});
}
上述代码中,DispatcherTimer是非UI线程中创建,定时任务中访问UI元素text1,需要通过Invoke或者BeginInvoke封送(marshal)到UI线程上运行,而Console.WriteLine则可以直接运行。System.Threading.PeriodicTimer(.NET 6+)
var stateTimer = new
var autoEvent = new AutoResetEvent(false);
Timer(CheckStatus, autoEvent, 1000,250);
private int invokeCount=0;
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",DateTime.Now.ToString("h:mm:ss.fff"),(++invokeCount).ToString());
if(invokeCount == 10)
{
invokeCount = 0;
autoEvent.Set();
}
}
System.Timers.Timerpublic partial class TimerFrom : Form
{
private System.Timers.Timer timer;
private void TimerFrom_Load(object sender, EventArgs e)
{
// 支持注册多个处理程序
timer.Elapsed += (sender, e) => { label1.Text = DateTime.Now.ToLongTimeString(); };
timer.Elapsed += (sender, e) => { Console.WriteLine(DateTime.Now.ToLongTimeString()); };
//自定义回调执行的方式(指定对象所在的线程),SynchronizingObject=null时在线程池上执行
timer.SynchronizingObject = this;
timer.AutoReset = true;
timer.Start();
}
}
本例中将SynchronizingObject属性设置为Form对象,因此Elapsed的处理程序在UI线程上执行,可以直接修改label1.Text,如果SynchronizingObject属性为null,处理程序则是在线程池线程上执行,修改label1.Text时需要通过Invoke或者BeginInvoke封送(marshal)到UI线程上运行。var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15));
using (var timer = new PeriodicTimer(TimeSpan.FromSeconds(1)))
{
try
{
while (await timer.WaitForNextTickAsync(cts.Token))
{
await Task.Delay(3000);
Console.WriteLine($"ThreadId is {Thread.CurrentThread.ManagedThreadId} --- Time is {DateTime.Now:HH:mm:ss}");
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation cancelled");
}
}
小结