C#中的Timers.Timer使用用法及常见报错
System.Timers.Timer 是一个基于服务器的计时器,它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境,并且不应该与用户界面(UI)直接交互。在 ASP.NET 中,通常使用 System.Timers.Timer 来处理周期性的任务。
主要使用步骤:
- System.Timers.Timer Timer1 = new System.Timers.Timer( 1000 ); //实例化 设置时间间隔
- Timer1 .Elapsed += 函数名; //给timer订阅事件
- Timer1.AutoReset = true; //设置是执行一次(false)还是一直执行(true);
- Timer1.Start();//激活事件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinCourseControls
{
public partial class test : Form
{
public test()
{
InitializeComponent();
}
System.Timers.Timer timer1 = new System.Timers.Timer();
private void test_Load(object sender, EventArgs e)
{
timer1 = new System.Timers.Timer();
timer1.Interval = 1000;
timer1.AutoReset = true;//执行一次还是重复执行
timer1.Elapsed += Timer1_Elapsed;//订阅事件
timer1.Start();
}
private void Timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//执行这里逻辑不是UI线程 ----子线程
this.Invoke(new Action(() => {
textBox1.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString();//主线程执行
}));
}
}
}
运行结果
常见异常1
事件处理程序中,执行的是子线程,不是主线程,不能直接修改里面的UI元素,想要修改可以通过窗口句柄或者控件的句柄的线程执行指定的委托才能修改UI元素。
如下直接修改UI元素:
报错:System.InvalidOperationException:“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”
常见异常2
以下案例是计算1+…+100的计算结果并把结果给点label控件,当关闭窗口页面时,子线程未运行结束会报错:System.ObjectDisposedException:“无法访问已释放的对象。
ObjectDisposed_ObjectName_Name”。当关闭页面时需要触发事件去关闭子线程,或者终断所有线程。
部分代码:
this.Invoke(new Action(() =>
{
total += num;
if(num <100)
{
label5.Text = num.ToString();
label8.Text = total.ToString();
num++;
}
else
{
timer2.Stop();
}
}));
}
运行结果:
可以添加FromClosing事件,当关闭页面时,定时器如果在激活状态也进行停止即可解决。
private void test_FormClosing(object sender, FormClosingEventArgs e)
{
if (timer2.Enabled )
{
timer2.Stop();
}
}