本文主要介绍.NET Core(C#) 中,使用System.Timers.Timer计时器实现定时任务的方法,以及相关的示例代码。

1、System.Threading.Timer、System.Windows.Forms.Timer和System.Timers.Timer区别

相关文档:

https://docs.microsoft.com/zh-tw/dotnet/api/system.windows.forms.timer?view=netcore-3.1

https://docs.microsoft.com/zh-tw/dotnet/api/system.timers.timer?view=netcore-3.1

https://docs.microsoft.com/zh-tw/dotnet/api/system.threading.timer?view=netcore-3.1


System.Timers.Timer :按固定间隔触发事件。 类旨在用作多线程环境中基于服务器的组件或服务组件;它没有用户界面,在运行时不可见。

System.Threading.Timer:按固定间隔在线程池线程上执行单个回调方法。 回调方法是在实例化计时器时定义的,无法更改。 与 System.Timers.Timer 类一样,此类用作多线程环境中基于服务器的或服务组件;它没有用户界面,在运行时不可见。

System.Windows.Forms.Timer:(仅 .NET Framework):定期触发事件的 Windows 窗体组件。 该组件没有用户界面,专门用于单线程环境。

System.Web.UI.Timer:(仅 .NET Framework):在固定时间间隔内执行异步或同步网页回发的 ASP.NET 组件。

System.Timers.TimerSystem.Threading.Timer是多线程的,时间到了,就会执行,之前的任务没有执行完成也不影响,因为还会开个新线程继续执行新的任务。

System.Windows.Forms.Timer是单线程的,只有之前的任务执行完成了,才会执行下次任务,这样上一次任务处理超过时间,下一次任务执行就会延时执行。

2、System.Timers.Timer相关说明文档

1)构造函数

Timer()

初始化 Timer 类的新实例,并将所有属性设置为初始值。

Timer(Double)

初始化 Timer 类的新实例,并将 Interval 属性设置为指定的毫秒数。

2)属性

AutoReset

获取或设置一个布尔值,该值指示 Timer 是否应只引发一次 Elapsed 事件((false) 或重复 (true))。

CanRaiseEvents

获取一个指示组件是否可以引发事件的值。(继承自 Component)

Container

获取包含 IContainer 的 Component。(继承自 Component)

DesignMode

获取一个值,用以指示 Component 当前是否处于设计模式。(继承自 Component)

Enabled

获取或设置一个值,该值指示 Timer 是否应引发 Elapsed 事件。

Events

获取附加到此 Component 的事件处理程序的列表。(继承自 Component)

Interval

获取或设置引发 Elapsed 事件的间隔(以毫秒为单位)。

Site

获取或设置在设计模式中将 Timer 绑定到其容器的站点。

SynchronizingObject

获取或设置对象,该对象用于在间隔过后封送发出的事件处理程序调用。3)

3)方法

BeginInit()

开始用于窗体或由其他组件使用的 Timer 的运行时初始化。

Close()

释放 Timer 使用的资源。

CreateObjRef(Type)

创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。(继承自 MarshalByRefObject)

Dispose()

释放 Component 使用的所有资源。(继承自 Component)

Dispose(Boolean)

释放由当前 Timer 使用的所有资源。

EndInit()

结束用于窗体或由其他组件使用的 Timer 的运行时初始化。

Equals(Object)

确定指定的对象是否等于当前对象。(继承自 Object)

GetHashCode()

作为默认哈希函数。(继承自 Object)

GetLifetimeService()

检索控制此实例的生存期策略的当前生存期服务对象。(继承自 MarshalByRefObject)

GetService(Type)

返回一个对象,该对象表示由 Component 或它的 Container 提供的服务。(继承自 Component)

GetType()

获取当前实例的 Type。(继承自 Object)

InitializeLifetimeService()

获取生存期服务对象来控制此实例的生存期策略。(继承自 MarshalByRefObject)

MemberwiseClone()

创建当前 Object 的浅表副本。(继承自 Object)

MemberwiseClone(Boolean)

创建当前 MarshalByRefObject 对象的浅表副本。(继承自 MarshalByRefObject)

Start()

通过将 Enabled 设置为 true 开始引发 Elapsed 事件。

Stop()

通过将 Enabled 设置为 false 停止引发 Elapsed 事件。

ToString()

返回包含 Component 的名称的 String(如果有)。 不应重写此方法。(继承自 Component)

4)事件

Disposed

在通过调用 Dispose() 方法释放组件时发生。(继承自 Component)

Elapsed

达到间隔时发生。

3、System.Timers.Timer使用示例代码

using System;
using System.Timers;
public class Example
{
   private static System.Timers.Timer aTimer;
   public static void Main()
   {
      SetTimer();
      Console.WriteLine("\nPress the Enter key to exit the application...\n");
      Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
      Console.ReadLine();
      aTimer.Stop();
      aTimer.Dispose();
      Console.WriteLine("Terminating the application...");
   }
   private static void SetTimer()
   {
        // Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }
    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
                          e.SignalTime);
    }
}
// The example displays output like the following:
//       Press the Enter key to exit the application...
//
//       The application started at 09:40:29.068
//       The Elapsed event was raised at 09:40:31.084
//       The Elapsed event was raised at 09:40:33.100
//       The Elapsed event was raised at 09:40:35.100
//       The Elapsed event was raised at 09:40:37.116
//       The Elapsed event was raised at 09:40:39.116
//       The Elapsed event was raised at 09:40:41.117
//       The Elapsed event was raised at 09:40:43.132
//       The Elapsed event was raised at 09:40:45.133
//       The Elapsed event was raised at 09:40:47.148
//
//       Terminating the application...

注意Timer 组件是基于服务器的计时器,在 Interval 属性中的毫秒数后,在应用程序中引发 Elapsed 事件。 您可以将 Timer 对象配置为只引发一次事件,或反复使用 AutoReset 属性引发事件。 通常,在类级别声明 Timer 对象,使其在需要时保持在范围内。 然后,可以处理其 Elapsed 事件以提供常规处理。 例如,假设你有一个关键服务器,该服务器必须每周7天、每天24小时保持运行。 你可以创建一个服务,该服务使用 Timer 对象定期检查服务器,并确保系统启动并运行。 如果系统未响应,则服务可能会尝试重新启动服务器或通知管理员。

另外,Timer 类并非适用于所有 .NET 实现和版本,如 .NET Standard 1.6 和更低版本。 在这些情况下,可以改用 System.Threading.Timer 类。

using System;
using System.Threading.Tasks;
using System.Timers;
class Example
{
   static void Main()
   {
      Timer timer = new Timer(1000);
      timer.Elapsed += async ( sender, e ) => await HandleTimer();
      timer.Start();
      Console.Write("Press any key to exit... ");
      Console.ReadKey();
   }
   private static Task HandleTimer()
   {
     Console.WriteLine("\nHandler not implemented..." );
     throw new NotImplementedException();
   }
}
// The example displays output like the following:
//   Press any key to exit...
//   Handler not implemented...
//   
//   Unhandled Exception: System.NotImplementedException: The method or operation is not implemented.
//      at Example.HandleTimer()
//      at Example.<<Main>b__0>d__2.MoveNext()
//   --- End of stack trace from previous location where exception was thrown ---
//      at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass2.<ThrowAsync>b__5(Object state)
//      at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
//      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
//      at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
//      at System.Threading.ThreadPoolWorkQueue.Dispatch()

如果 nullSynchronizingObject 属性,则在 ThreadPool 线程上引发 Elapsed 事件。 如果 Elapsed 事件的处理持续时间超过 Interval,则可能会在其他 ThreadPool 线程上再次引发该事件。 在这种情况下,事件处理程序应该是可重入的。

注意:

事件处理方法可能在一个线程上运行,同时另一个线程调用 Stop 方法或将 Enabled 属性设置为 false。 这可能导致计时器停止后引发 Elapsed 事件。 Stop 方法的代码示例演示了一种避免此争用条件的方法。

相关文档:.NET Core(C#) System.Threading.Timer使用实现定时任务及示例代码

推荐文档