解析.NET中几种Timer的使用

作者:Yang-Fei 时间:2023-05-21 17:27:53 

这篇博客将梳理一下.NET中4个Timer类,及其用法。

1. System.Threading.Timer

public Timer(TimerCallback callback, object state, int dueTime, int period);

callback委托将会在period时间间隔内重复执行,state参数可以传入想在callback委托中处理的对象,dueTime标识多久后callback开始执行,period标识多久执行一次callback。


using System.Threading;
// System.Threading.Timer
Timer timer = new Timer(delegate
{
Console.WriteLine($"Timer Thread: {Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"Is Thread Pool: {Thread.CurrentThread.IsThreadPoolThread}");
Console.WriteLine("Timer Action.");
},
null,
2000,
);
Console.WriteLine("Main Action.");
Console.WriteLine($"Main Thread: {Thread.CurrentThread.ManagedThreadId}");
Console.ReadLine();

解析.NET中几种Timer的使用

Timer回掉方法执行是在另外ThreadPool中一条新线程中执行的。

2. System.Timers.Timer

System.Timers.Timer和System.Threading.Timer相比,提供了更多的属性,

Interval指定执行Elapsed事件的时间间隔;

Elapsed指定定期执行的事件;

Enabled用于Start/Stop Timer;

Start 开启Timer

Stop 停止Timer


System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 500;
timer.Elapsed += delegate
{
Console.WriteLine($"Timer Thread: {Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"Is Thread Pool: {Thread.CurrentThread.IsThreadPoolThread}");
Console.WriteLine("Timer Action");
timer.Stop();
};
timer.Start();
Console.WriteLine("Main Action.");
Console.WriteLine($"Main Thread: {Thread.CurrentThread.ManagedThreadId}");
Console.ReadLine();

解析.NET中几种Timer的使用

Timer Elapsed定期任务是在ThreadPool的线程中执行的。

3. System.Windows.Forms.Timer

Interval指定执行Elapsed事件的时间间隔;

Tick     指定定期执行的事件;

Enabled用于Start/Stop Timer;

Start 开启Timer

Stop 停止Timer

使用System.Windows.Forms.Timer来更新窗体中Label内时间,


using System.Windows.Forms;
public Form1()
{
InitializeComponent();
this.Load += delegate
{
Timer timer = new Timer();
timer.Interval = 500;
timer.Tick += delegate
{
System.Diagnostics.Debug.WriteLine($"Timer Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
System.Diagnostics.Debug.WriteLine($"Is Thread Pool: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
this.lblTimer.Text = DateTime.Now.ToLongTimeString();
};
timer.Start();
System.Diagnostics.Debug.WriteLine($"Main Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
};
}

解析.NET中几种Timer的使用

Timer Tick事件中执行的事件线程与主窗体的线程是同一个,并没有创建新线程(或者使用ThreadPool中线程)来更新UI。下面将代码做一个改动,使用System.Timers.Timer来更新UI上的时间,代码如下,


public Form1()
{
InitializeComponent();
this.Load += delegate
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 500;
timer.Elapsed += delegate
{
System.Diagnostics.Debug.WriteLine($"Timer Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
System.Diagnostics.Debug.WriteLine($"Is Thread Pool: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
this.lblTimer.Text = DateTime.Now.ToLongTimeString();
};
timer.Start();
System.Diagnostics.Debug.WriteLine($"Main Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
};
}

解析.NET中几种Timer的使用

很熟悉的一个错误。因为Label是由UI线程创建的,所以对其进行修改需要在UI线程中进行。System.Timers.Timer中Elasped执行是在ThreadPool中新创建的线程中执行的。所以会有上面的错误。

4. System.Windows.Threading.DispatcherTimer

属性和方法与System.Windows.Forms.Timer类似。


using System.Windows.Threading;
public MainWindow()
{
InitializeComponent();
this.Loaded += delegate
{
//DispatcherTimer
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Start();
Debug.WriteLine($"Main Thread Id: {Thread.CurrentThread.ManagedThreadId}");
timer.Tick += delegate
{
tbTime.Text = DateTime.Now.ToLongTimeString();
Debug.WriteLine($"Timer Thread Id: {Thread.CurrentThread.ManagedThreadId}");
timer.Stop();
};
};
}

解析.NET中几种Timer的使用

DispatcherTimer中Tick事件执行是在主线程中进行的。

使用DispatcherTimer时有一点需要注意,因为DispatcherTimer的Tick事件是排在Dispatcher队列中的,当系统在高负荷时,不能保证在Interval时间段执行,可能会有轻微的延迟,但是绝对可以保证Tick的执行不会早于Interval设置的时间。如果对Tick执行时间准确性高可以设置DispatcherTimer的priority。例如:

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Send);

来源:http://www.cnblogs.com/yang-fei/p/6169089.html

标签:.NET,Timer
0
投稿

猜你喜欢

  • JavaWeb开发之使用jQuery与Ajax实现动态联级菜单效果

    2023-11-28 19:46:08
  • Java Swing组件编程之JTable表格用法实例详解

    2022-12-23 01:49:26
  • 如何利用Jackson序列化忽略指定类型的属性详解

    2023-11-16 09:01:27
  • C# javascript 读写Cookie的方法

    2023-03-19 08:03:16
  • Android中实现TCP和UDP传输实例

    2021-11-08 14:19:59
  • C#操作DataGridView获取或设置当前单元格的内容

    2022-04-01 14:44:25
  • Java8中的LocalDateTime和Date一些时间操作方法

    2022-06-28 12:28:57
  • Android SharedPreferences存储用法详解

    2023-08-07 08:25:34
  • maven多个仓库查询的优先级顺序案例讲解

    2023-08-16 02:33:23
  • 关于Spring Boot获取bean的3种方式

    2023-07-08 11:52:15
  • Qt GUI图形图像开发之Qt表格控件QTableView简单使用方法及QTableView与QTableWidget区别

    2022-02-23 05:02:59
  • Android中使用ZXing生成二维码(支持添加Logo图案)

    2023-12-24 21:34:58
  • Java中的ArrayList容量及扩容方式

    2023-10-17 17:24:40
  • Java实现图片倒影的源码实例内容

    2022-08-30 02:39:24
  • C# 扩展方法小结

    2022-12-25 22:43:34
  • C#通过指针读取文件的方法

    2023-02-21 03:08:10
  • Android编程之自定义锁屏实例分析

    2022-02-02 04:01:50
  • springboot 防止重复请求防止重复点击的操作

    2021-09-19 16:03:00
  • Android RecyclerView添加搜索过滤器的示例代码

    2022-03-08 21:44:49
  • datatable去掉重复行的方法

    2023-09-02 19:59:41
  • asp之家 软件编程 m.aspxhome.com