C# 定时器:你需要知道的一切

计时器在 C# 中对于 UI 编程、游戏和具有基于时间间隔的逻辑的应用程序非常有用。

C# 通过 .NET 提供的计时器可以轻松地对时间间隔进行计时,也可以在特定的时间间隔内执行特定的任务。

C# Timer 类是一个 .NET 类,可帮助您创建将按设定时间间隔发生的事件。该界面使启动和停止计时器或启用和禁用它变得容易。

定时器使用

使用计时器类时的关键术语是:

  • Interval:两次连续调用 Elapsed 函数之间的时间间隔。
  • 回调:定时器在结束时调用此方法。
  • AutoReset:布尔值,用于确定计时器是否会在每次经过指定的时间间隔时引发 Tick 事件。

要在 C# 中使用计时器,请按照下列步骤操作:

  1. 用您想要的毫秒间隔设置计时器。

    C#
    System.Timers.Timer timer = new (interval: 1000);
  2. 定义Elapsed事件处理程序。每次经过 interval 毫秒后,计时器都会调用此处理程序。

    C#
      void HandleTimer()
      { 
        Console.WriteLine("Interval Called");
      }
  3. 设置计时器以调用您的事件处理程序:

    C#
     timer.Elapsed += ( sender, e ) => HandleTimer();
  4. 调用 Start() 方法启动计时器。

    C#
    timer.Start();
  5. 完成计时器后,调用 Dispose() 方法释放计时器使用的资源。

    C#
      timer.Dispose();

把它们放在一起:

C#
using System;					
public class Program
{
	public static void Main()
	{		
		void HandleTimer()
		{
			Console.WriteLine("Interval Called");
		}
		System.Timers.Timer timer = new (interval: 1000 );
		timer.Elapsed += ( sender, e ) => HandleTimer();
		timer.Start();

		Console.ReadLine(); // To make sure the console app keeps running.
    System.Threading.Thread.Sleep(10000);

    timer.Dispose();
	}
}

加等事件

C# 中的 +=(加等于)语法是定义事件处理程序的快捷方式。它告诉计时器订阅事件处理程序。

如果需要,我们也可以使用 -=(减去等于)来取消订阅。

区间限制

C# 定时器依赖于系统时钟。

系统时钟的分辨率是 Elapsed 事件触发的频率。如果您将 Interval 属性设置为小于解析系统时钟,则它不会以所需的时间间隔触发。

对于大多数用例来说这不是问题。但如果您正在寻找高分辨率计时器,请考虑使用 Stopwatch 类。

处置

Timer 类实现 System.IDisposable 接口,以在处理时释放由它分配的系统资源。

使用 C# 时的最佳实践表明,如果该类实现了 IDisposable 接口,您应该清理资源。

有两种方法可以处理 Timer:

  • 通过在 try/catch 块中调用 Dispose() 方法来处理计时器以避免异常。
  • using清理特定范围时,使用该指令自动调用 Dispose 方法。这将避免额外的 try/catch 块和代码行来正确清理。

微软说要处理 IDisposable 对象。

异步定时器

System.Timers.Timer 类支持异步事件处理程序以在所需的时间间隔触发事件。要定义异步事件处理程序,请async在 Elapsed 事件处理程序的签名之前使用修饰符。

例子:

C#
using System;
using System.Threading.Tasks;

Task HandleTimerAsync()
{
    Console.WriteLine("Interval Called");
    // Your async logic here.
    return Task.CompletedTask;
}


System.Timers.Timer timer = new (interval: 1000 );
timer.Elapsed += async ( sender, e ) => await HandleTimerAsync();
timer.Start();

System.Console.WriteLine("Start");
System.Threading.Thread.Sleep(5000);

请记住,异步回调必须返回一个任务。如果异步方法运行时间超过间隔时间,您可能会得到一些意想不到的结果。

→ 阅读更多:C# 异步与同步

.NET 中的不同计时器

在 .NET 中,有 4 种不同的计时器,具体取决于您希望使用它们的方式:

  • 系统.Windows.Forms.Timer
  • System.Web.UI.Timer
  • 系统.定时器.定时器
  • 系统线程计时器

系统.Windows.Forms.Timer

System.Windows.Forms.Timer 类专为丰富的客户端用户界面而设计。

程序员可以将其作为非可视控件拖到窗体中,并从“属性”窗口中调节行为。它将始终安全地从可以与用户界面交互的线程中触发事件。

系统.Web.UI.Timer

System.Web.UI.Timer 可以以定义的时间间隔异步或同步执行网页回发。它是 ASP.NET 框架的一部分,因此我们只能在 ASP.NET Web 应用程序中使用它。

此计时器可用于在 ASP.NET 应用程序上创建实时信息显示。

系统线程计时器

System.Threading.Timer 提供了在后台线程上异步或同步安排单个回调的能力。

System.Threading.Timer 是线程安全的。

系统.定时器.定时器

System.Timers.Timer 是在 C# 中实现计时器的最佳方式。

System.Timers.Timer 是 System.Threading.Timer 的包装器,对功能进行抽象和分层。

您不能将 System.Threading.Timer 用作组件容器中的组件,它实现了 System.ComponentModel.IContainer,因为它不是从 System.ComponentModel.Component 派生的。

System.Timers.Timer 扩展了 System.Timers.Timer 的功能以包含组件容器应用程序所需的功能。

System.Timers.Timer 和 System.Threading.Timer 都是为在服务器类型的进程中使用而设计的,但是 System.Timers.Timer 包含一个同步对象以允许它与用户界面交互,这对于需要跟踪用户输入或更新。

什么时候使用哪个定时器?

请遵循以下准则来选择要使用的一个:

  • System.Windows.Forms.Timer - 对于 Windows 窗体应用程序,在窗体的 UI 线程上运行委托。
  • System.Web.UI.Timer - 用于 ASP.NET 组件。它允许您定期执行异步或同步网页回发。
  • System.Threading.Timer - 非常适合线程池上的后台任务。
  • System.Timers.Timer - 使用更简单的 API 包装 System.Threading.Timer。我们大部分时间都使用这个。

C# 定时器精度

C# 计时器不准确。根据劳伦斯科技大学的研究,计时器平均比预期时间长 9.07% 。

要获得准确的时间,我们需要使用 .NET StopWatch 类。

系统.诊断.秒表

秒表类用于计时代码执行。它可以启动、停止/暂停和重置。

C# Stopwatch 和 C# Timers 之间的主要区别在于,当 Timer 在特定时间间隔过去时触发事件,而 Stopwatch 计算自开始以来经过了多少时间。此外,秒表更准确,可以更精确地测量时间。

如果您想要高分辨率计时器,请考虑使用秒表而不是计时器。

秒表实现源代码。

EventHandler 与 ElapsedEventHandler

EventHandler 和 ElapsedEventHandler 之间的主要区别在于 EventHandler 更通用,而 ElapsedEventHandler 使用具有特定签名的委托。

ElapsedEventHandler 是传递 ElapsedEventArgs 的委托,它通过添加FileTime和扩展 EventHandler 的参数SignalTime。添加的逻辑使 ElapsedEventHandler 委托与 ElapsedEventArgs 兼容。

ElapsedEventArgs 实现源代码。

常问问题

C#中的事件是什么?

C# 中的事件是类让客户知道对象何时发生有趣事件的一种方式。我们使用委托声明事件。

术语订阅和取消订阅有时用于表示某个类对特定事件感兴趣并想知道它何时发生。

我们通常不需要事件参数,因此我们可以将其作为事件处理程序中的可选参数来实现。

如何在 C# 中命名事件?

命名约定建议用过去时命名事件。例如,OrderPlaced、OrderShipped 等。

该约定还建议将事件处理程序命名为事件名称和后缀的组合EventHandler。对于上述事件,事件处理程序将命名为OrderPlacedEventHandlerOrderShippedEventHandler

结论

计时器是在 C# 中处理基于时间的操作的好方法。它们可用于从 UI 编程到游戏逻辑等所有方面。

计时器类易于使用,并且可以轻松设置将在特定时间间隔发生的事件。

为了在 C# 中使用计时器,您必须首先使用所需的时间间隔设置计时器,然后定义 Elapsed 事件处理程序。计时器启动后,每次经过指定的时间间隔时都会调用事件处理程序。

如果您需要高分辨率计时器,请考虑使用 Stopwatch 类。使用完计时器后,请确保通过调用 Dispose() 方法正确处理它。

.NET 提供了多种计时器来满足您的需要,具体取决于您希望如何使用它们。System.Windows.Forms.Timer 专为丰富的客户端用户界面而设计,可以在“属性”窗口中进行调节。System.Web.UI.Timer 可用于 ASP.NET Web 应用程序以创建实时信息显示,而 System.Threading.Timer 非常适合线程池上的后台任务。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值