解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# ¸ß¼¶¶¨Ê±Æ÷TimerX
## ¸ÅÊö
`NewLife.Threading.TimerX` ÊÇÒ»¸ö¹¦ÄÜÇ¿´óµÄ¶¨Ê±Æ÷ʵÏÖ£¬Ïà±Èϵͳ `System.Threading.Timer` ¾ßÓÐÒÔÏÂÓÅÊÆ£º
- **²»¿ÉÖØÈë**£º»Øµ÷Ö´ÐÐÍê±Ïºó²Å¿ªÊ¼¼ÆÊ±ÏÂÒ»´Î
- **Ö§³ÖÒì²½»Øµ÷**£ºÔÉúÖ§³Ö `async/await`
- **¾ø¶Ôʱ¼äÖ´ÐÐ**£ºÖ§³Ö¹Ì¶¨Ê±¿ÌÖ´ÐУ¨ÈçÿÌì2µã£©
- **Cron ±í´ïʽ**£ºÖ§³Ö¸´ÔӵĶ¨Ê±¹æÔò
- **Á´Â·×·×Ù**£ºÄÚÖà `ITracer` ÂñµãÖ§³Ö
- **°²È«ÊÍ·Å**£º¹ÒÔØÔÚ¾²Ì¬µ÷¶ÈÆ÷ÉÏ£¬±ÜÃâ±»GCÌáǰ»ØÊÕ
**ÃüÃû¿Õ¼ä**: `NewLife.Threading`
**Ô´Âë**: [NewLife.Core/Threading/TimerX.cs](https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/TimerX.cs)
---
## ¿ìËÙÈëÃÅ
### »ù´¡Ó÷¨£ºÖÜÆÚÐÔÖ´ÐÐ
```csharp
using NewLife.Threading;
// 1ÃëºóÊ×´ÎÖ´ÐУ¬È»ºóÿ5ÃëÖ´ÐÐÒ»´Î
var timer = new TimerX(state =>
{
Console.WriteLine($"Ö´ÐÐʱ¼ä£º{DateTime.Now}");
}, null, 1000, 5000);
// ʹÓÃÍê±Ï¼ÇµÃÊÍ·Å
timer.Dispose();
```
**²ÎÊý˵Ã÷**£º
- `state`£ºÓû§Êý¾Ý£¬»á´«µÝ¸ø»Øµ÷º¯Êý
- `dueTime`£ºÑÓ³Ùʱ¼ä£¨ºÁÃ룩£¬Ê×´ÎÖ´ÐÐǰµÈ´ýµÄʱ¼ä
- `period`£º¼ä¸ôÖÜÆÚ£¨ºÁÃ룩£¬ÉèΪ0»ò-1±íʾִֻÐÐÒ»´Î
### Òì²½»Øµ÷
```csharp
// Ö§³Ö async/await µÄÒì²½»Øµ÷
var timer = new TimerX(async state =>
{
await Task.Delay(100); // Ä£ÄâÒì²½²Ù×÷
Console.WriteLine("Òì²½ÈÎÎñÍê³É");
}, null, 1000, 5000);
```
**×Ô¶¯ÉèÖÃ**£º
- ʹÓà `Func<Object, Task>` ʱ£¬×Ô¶¯ÉèÖà `IsAsyncTask = true` ºÍ `Async = true`
### ¾ø¶Ôʱ¼äÖ´ÐÐ
```csharp
// ÿÌìÁ賿2µãÖ´ÐÐ
var start = DateTime.Today.AddHours(2);
var timer = new TimerX(state =>
{
Console.WriteLine("Ö´ÐÐÊý¾ÝÇåÀíÈÎÎñ");
}, null, start, 24 * 3600 * 1000); // ÖÜÆÚ24Сʱ
```
**ÌØµã**£º
- Èç¹û `startTime` СÓÚµ±Ç°Ê±¼ä£¬»á×Ô¶¯¼Ó `period` Ö±µ½´óÓÚµ±Ç°Ê±¼ä
- ×Ô¶¯ÉèÖà `Absolutely = true`
- ²»ÊÜ `SetNext` Ó°Ï죬ʼÖÕÔڹ̶¨Ê±¿ÌÖ´ÐÐ
### Cron ±í´ïʽ
```csharp
// ÿ¸ö¹¤×÷ÈÕÔçÉÏ9µãÖ´ÐÐ
var timer = new TimerX(state =>
{
Console.WriteLine("¹¤×÷ÈÕÈÎÎñ");
}, null, "0 0 9 * * 1-5");
// Ö§³Ö¶à¸öCron±í´ïʽ£¬·ÖºÅ·Ö¸ô
var timer2 = new TimerX(state =>
{
Console.WriteLine("»ìºÏÈÎÎñ");
}, null, "0 0 2 * * 1-5;0 0 3 * * 6"); // ¹¤×÷ÈÕ2µã£¬ÖÜÁù3µã
```
**×Ô¶¯ÉèÖÃ**£º
- ʹÓà Cron ±í´ïʽʱ£¬×Ô¶¯ÉèÖà `Absolutely = true`
- ÏÂÒ»´ÎÖ´ÐÐʱ¼äÓÉ Cron ¼ÆËã
---
## ºËÐÄÌØÐÔ
### 1. ²»¿ÉÖØÈë»úÖÆ
ϵͳ `Timer` µÄÎÊÌ⣺
```csharp
// System.Threading.Timer µÄÎÊÌâ
var timer = new Timer(_ =>
{
Thread.Sleep(3000); // ¼ÙÉèÈÎÎñºÄʱ3Ãë
Console.WriteLine("Ö´ÐÐ");
}, null, 0, 1000); // ÿ1Ãë´¥·¢
// ½á¹û£º¿ÉÄÜͬʱÓжà¸ö»Øµ÷ÔÚÖ´ÐУ¬Ôì³É²¢·¢ÎÊÌ⣡
```
TimerX µÄ½â¾ö·½°¸£º
```csharp
var timer = new TimerX(_ =>
{
Thread.Sleep(3000); // ºÄʱ3Ãë
Console.WriteLine("Ö´ÐÐ");
}, null, 0, 1000);
// Ö´ÐÐÁ÷³Ì£º
// 0Ã룺¿ªÊ¼µÚ1´ÎÖ´ÐÐ
// 3Ã룺µÚ1´ÎÖ´ÐÐÍê±Ï£¬µÈ´ý1Ãë
// 4Ã룺¿ªÊ¼µÚ2´ÎÖ´ÐÐ
// 7Ã룺µÚ2´ÎÖ´ÐÐÍê±Ï£¬µÈ´ý1Ãë
// 8Ã룺¿ªÊ¼µÚ3´ÎÖ´ÐÐ
// ...
```
**ÔÀí**£º»Øµ÷Ö´ÐÐÍê±Ïºó²Å¿ªÊ¼¼ÆËãÏÂÒ»´ÎµÄÑÓ³Ùʱ¼ä£¬È·±£Í¬Ò»Ê±¿ÌÖ»ÓÐÒ»¸ö»Øµ÷ÔÚÖ´ÐС£
### 2. »ùÓÚ TickCount µÄ¾«×¼¼ÆÊ±
TimerX ʹÓà `Runtime.TickCount64` ×÷Ϊ¼ÆÊ±»ù×¼£¬ÎÞ¾åϵͳʱ¼ä»Ø²¦£º
```csharp
// ¼´Ê¹ÊÖ¶¯µ÷Õûϵͳʱ¼ä£¬TimerX Ò²²»ÊÜÓ°Ïì
var timer = new TimerX(_ =>
{
Console.WriteLine($"Ö´ÐУº{DateTime.Now}");
}, null, 0, 5000);
```
**ÓÅÊÆ**£º
- ʹÓÿª»úàÖàªÊý¶ø·ÇϵͳʱÖÓ
- ²»ÊÜÏÄÁîʱ¡¢Ê±Çøµ÷ÕûÓ°Ïì
- ÿ´Î `SetNextTick` »áË¢ÐÂʱ¼ä»ù×¼£¬×Ô¶¯ÐÞÕýÆ¯ÒÆ
### 3. ¾ø¶Ôʱ¼äÓë Cron
- **`Absolutely = true`**£º±íʾ¾ø¶Ôʱ¼äÖ´ÐУ¬²»ÊÜ `SetNext` Ó°Ïì
- **Cron ¹¹Ô캯Êý**£º×Ô¶¯ÉèÖà `Absolutely = true`£¬Í¨¹ý `Cron.GetNext(now)` ¼ÆËãÏÂÒ»´ÎÖ´ÐÐʱ¼ä
```csharp
// ¾ø¶Ôʱ¼ä¶¨Ê±Æ÷
var timer = new TimerX(_ => { }, null, DateTime.Today.AddHours(2), 24 * 3600 * 1000);
timer.Absolutely; // true
// Cron ¶¨Ê±Æ÷
var timer2 = new TimerX(_ => { }, null, "0 0 2 * * *");
timer2.Absolutely; // true
timer2.Crons; // CronÊý×é
```
---
## ¹¹Ô캯ÊýÏê½â
### 1. ÆÕͨÖÜÆÚ¶¨Ê±Æ÷£¨Í¬²½£©
```csharp
public TimerX(TimerCallback callback, Object? state, Int32 dueTime, Int32 period, String? scheduler = null)
```
**²ÎÊý**£º
- `callback`: »Øµ÷ίÍÐ `void Callback(Object state)`
- `state`: Óû§Êý¾Ý
- `dueTime`: ÑÓ³Ùʱ¼ä£¨ºÁÃ룩£¬Ê×´ÎÖ´ÐÐǰµÈ´ý
- `period`: ¼ä¸ôÖÜÆÚ£¨ºÁÃ룩£¬0»ò-1±íʾִֻÐÐÒ»´Î
- `scheduler`: µ÷¶ÈÆ÷Ãû³Æ£¬Ä¬ÈÏʹÓà `TimerScheduler.Default`
**ʾÀý**£º
```csharp
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
}, null, 1000, 5000);
```
### 2. Òì²½ÖÜÆÚ¶¨Ê±Æ÷
```csharp
public TimerX(Func<Object, Task> callback, Object? state, Int32 dueTime, Int32 period, String? scheduler = null)
```
**²ÎÊý**£º
- `callback`: Òì²½»Øµ÷ίÍÐ `async Task Callback(Object state)`
- ÆäËû²ÎÊýͬÉÏ
**×Ô¶¯ÉèÖÃ**£º
- `IsAsyncTask = true`
- `Async = true`
**ʾÀý**£º
```csharp
var timer = new TimerX(async _ =>
{
await DoWorkAsync();
}, null, 1000, 5000);
```
### 3. ¾ø¶Ôʱ¼ä¶¨Ê±Æ÷£¨Í¬²½£©
```csharp
public TimerX(TimerCallback callback, Object? state, DateTime startTime, Int32 period, String? scheduler = null)
```
**²ÎÊý**£º
- `startTime`: ¾ø¶Ô¿ªÊ¼Ê±¼ä£¬Ö¸¶¨Ê±¿ÌÖ´ÐÐ
- `period`: ¼ä¸ôÖÜÆÚ£¨ºÁÃ룩£¬±ØÐë´óÓÚ0
**×Ô¶¯ÉèÖÃ**£º
- `Absolutely = true`
- Èç¹û `startTime` СÓÚµ±Ç°Ê±¼ä£¬×Ô¶¯¼Ó `period` ¶ÔÆë
**ʾÀý**£º
```csharp
// ÿÌìÁ賿2µãÖ´ÐÐ
var start = DateTime.Today.AddHours(2);
var timer = new TimerX(_ =>
{
Console.WriteLine("Á賿ÈÎÎñ");
}, null, start, 24 * 3600 * 1000);
```
### 4. ¾ø¶Ôʱ¼ä¶¨Ê±Æ÷£¨Òì²½£©
```csharp
public TimerX(Func<Object, Task> callback, Object? state, DateTime startTime, Int32 period, String? scheduler = null)
```
**×Ô¶¯ÉèÖÃ**£º
- `IsAsyncTask = true`
- `Async = true`
- `Absolutely = true`
### 5. Cron ¶¨Ê±Æ÷£¨Í¬²½£©
```csharp
public TimerX(TimerCallback callback, Object? state, String cronExpression, String? scheduler = null)
```
**²ÎÊý**£º
- `cronExpression`: Cron ±í´ïʽ£¬Ö§³Ö·ÖºÅ·Ö¸ô¶à¸ö±í´ïʽ
**×Ô¶¯ÉèÖÃ**£º
- `Absolutely = true`
- ½âÎö±í´ïʽ²¢±£´æµ½ `_crons` Êý×é
**ʾÀý**£º
```csharp
// ÿ¸ö¹¤×÷ÈÕÔçÉÏ9µã
var timer = new TimerX(_ =>
{
Console.WriteLine("¹¤×÷ÈÕÈÎÎñ");
}, null, "0 0 9 * * 1-5");
// ¶à¸öʱ¼äµã
var timer2 = new TimerX(_ =>
{
Console.WriteLine("»ìºÏÈÎÎñ");
}, null, "0 0 2 * * 1-5;0 0 3 * * 6");
```
### 6. Cron ¶¨Ê±Æ÷£¨Òì²½£©
```csharp
public TimerX(Func<Object, Task> callback, Object? state, String cronExpression, String? scheduler = null)
```
**×Ô¶¯ÉèÖÃ**£º
- `IsAsyncTask = true`
- `Async = true`
- `Absolutely = true`
---
## ºËÐÄÊôÐÔ
| ÊôÐÔ | ÀàÐÍ | ˵Ã÷ |
|-----|------|------|
| `Id` | Int32 | ¶¨Ê±Æ÷Ψһ±êʶ£¬×Ô¶¯·ÖÅä |
| `Period` | Int32 | ¼ä¸ôÖÜÆÚ£¨ºÁÃ룩£¬0»ò-1±íʾִֻÐÐÒ»´Î |
| `Async` | Boolean | ÊÇ·ñÒì²½Ö´ÐУ¬Ä¬ÈÏ false |
| `Absolutely` | Boolean | ÊÇ·ñ¾ø¶Ô¾«È·Ê±¼äÖ´ÐУ¬Ä¬ÈÏ false |
| `Calling` | Boolean | »Øµ÷ÊÇ·ñÕýÔÚÖ´ÐУ¨Ö»¶Á£© |
| `Timers` | Int32 | ÀۼƵ÷ÓôÎÊý£¨Ö»¶Á£© |
| `Cost` | Int32 | ƽ¾ùºÄʱ£¨ºÁÃ룬ֻ¶Á£© |
| `NextTime` | DateTime | ÏÂÒ»´Îµ÷ÓÃʱ¼ä£¨Ö»¶Á£© |
| `NextTick` | Int64 | ÏÂÒ»´ÎÖ´ÐÐʱ¼äµÄàÖàªÊý£¨Ö»¶Á£© |
| `Crons` | Cron[] | Cron ±í´ïʽ¼¯ºÏ£¨Ö»¶Á£© |
| `Tracer` | ITracer | Á´Â·×·×ÙÆ÷ |
| `TracerName` | String | Á´Â·×·×ÙÃû³Æ£¬Ä¬ÈÏ `timer:{·½·¨Ãû}` |
| `State` | Object | Óû§Êý¾Ý£¬ÈõÒýÓô洢 |
| `Scheduler` | TimerScheduler | ËùÊôµ÷¶ÈÆ÷ |
---
## ºËÐÄ·½·¨
### SetNext - ÉèÖÃÏÂÒ»´ÎÖ´ÐÐʱ¼ä
```csharp
/// <summary>ÉèÖÃÏÂÒ»´ÎÔËÐÐʱ¼ä</summary>
/// <param name="ms">ÑÓ³ÙºÁÃëÊý¡£Ð¡ÓÚµÈÓÚ0±íʾÂíÉϵ÷¶È</param>
public void SetNext(Int32 ms)
```
**ʾÀý**£º
```csharp
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
// ¶¯Ì¬µ÷ÕûÏÂÒ»´ÎÖ´ÐÐʱ¼ä
if (someCondition)
timer.SetNext(10000); // 10ÃëºóÖ´ÐÐ
else
timer.SetNext(1000); // 1ÃëºóÖ´ÐÐ
}, null, 1000, 5000);
```
**×¢Òâ**£º
- ¶ÔÓÚ `Absolutely = true` µÄ¶¨Ê±Æ÷£¨¾ø¶Ôʱ¼ä¡¢Cron£©£¬`SetNext` ÎÞЧ
- µ÷Óúó»á»½Ðѵ÷¶ÈÆ÷Á¢¼´¼ì²é
### Change - ¸ü¸Ä¼ÆÊ±Æ÷²ÎÊý
```csharp
/// <summary>¸ü¸Ä¼ÆÊ±Æ÷µÄÆô¶¯Ê±¼äºÍ·½·¨µ÷ÓÃÖ®¼äµÄʱ¼ä¼ä¸ô</summary>
/// <param name="dueTime">ÑÓ³Ùʱ¼ä</param>
/// <param name="period">¼ä¸ôÖÜÆÚ</param>
/// <returns>ÊÇ·ñ³É¹¦¸ü¸Ä</returns>
public Boolean Change(TimeSpan dueTime, TimeSpan period)
```
**ʾÀý**£º
```csharp
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
}, null, 1000, 5000);
// ÐÞ¸ÄΪ2ÃëºóÊ×´ÎÖ´ÐУ¬È»ºóÿ10ÃëÒ»´Î
timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10));
```
**ÏÞÖÆ**£º
- ¶ÔÓÚ `Absolutely = true` µÄ¶¨Ê±Æ÷£¬·µ»Ø false£¬ÐÞ¸Äʧ°Ü
- ¶ÔÓÚ Cron ¶¨Ê±Æ÷£¬·µ»Ø false£¬ÐÞ¸Äʧ°Ü
- `period` Ϊ¸ºÊý»ò Infinite ʱ£¬¶¨Ê±Æ÷»á±»Ïú»Ù
### Dispose - Ïú»Ù¶¨Ê±Æ÷
```csharp
/// <summary>Ïú»Ù¶¨Ê±Æ÷</summary>
public void Dispose()
```
**ʾÀý**£º
```csharp
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
}, null, 1000, 5000);
// ʹÓÃÍê±ÏÊÍ·Å
timer.Dispose();
```
**ÖØÒªÐÔ**£º
- TimerX ¹ÒÔØÔÚ¾²Ì¬µ÷¶ÈÆ÷ `TimerScheduler` ÉÏ
- **±ØÐëÊÖ¶¯µ÷Óà `Dispose()`** ²ÅÄÜ´Óµ÷¶ÈÆ÷ÒÆ³ý
- ·ñÔò»áÔì³ÉÄÚ´æÐ¹Â©ºÍ¶¨Ê±Æ÷¼ÌÐøÖ´ÐÐ
---
## ¾²Ì¬·½·¨
### Delay - ÑÓ³ÙÖ´ÐÐ
```csharp
/// <summary>ÑÓ³ÙÖ´ÐÐÒ»¸öίÍÐ</summary>
/// <param name="callback">»Øµ÷ίÍÐ</param>
/// <param name="ms">ÑÓ³ÙºÁÃëÊý</param>
/// <returns>¶¨Ê±Æ÷ʵÀý</returns>
public static TimerX Delay(TimerCallback callback, Int32 ms)
```
**ʾÀý**£º
```csharp
// 10ÃëºóÖ´ÐÐÒ»´Î£¬È»ºóÏú»Ù
var timer = TimerX.Delay(_ =>
{
Console.WriteLine("ÑÓ³ÙÈÎÎñÖ´ÐÐ");
}, 10000);
// ×¢Ò⣺ίÍпÉÄÜ»¹Ã»Ö´ÐУ¬timer¶ÔÏó¾Í±»GC»ØÊÕÁË
// ½¨Òé±£³ÖtimerÒýÓÃ
```
**×¢Òâ**£º
- ×Ô¶¯ÉèÖà `Async = true`
- ½öÖ´ÐÐÒ»´Î£¨Period=0£©
- **¾¯¸æ**£ºÈç¹û²»±£³Ö `timer` ÒýÓ㬿ÉÄܱ» GC »ØÊÕµ¼ÖÂδִÐÐ
### Now - »º´æµÄµ±Ç°Ê±¼ä
```csharp
/// <summary>µ±Ç°Ê±¼ä¡£¶¨Ê±¶Áȡϵͳʱ¼ä£¬±ÜÃâÆµ·±¶ÁÈ¡Ôì³ÉÐÔÄÜÆ¿¾±</summary>
public static DateTime Now { get; }
```
**ʾÀý**£º
```csharp
var now = TimerX.Now; // ÐÔÄÜÓÅÓÚ DateTime.Now
Console.WriteLine(now);
```
**ÔÀí**£º
- ÿ500ºÁÃë¸üÐÂÒ»´Îϵͳʱ¼ä
- ±ÜÃâÆµ·±µ÷Óà `DateTime.Now` Ôì³ÉÐÔÄÜÆ¿¾±
- ÊÊÓÃÓÚ¶Ôʱ¼ä¾«¶ÈÒªÇ󲻸ߵij¡¾°£¨¡À500ms£©
---
## µ÷¶ÈÆ÷ TimerScheduler
TimerX ÒÀÀµ `TimerScheduler` ½øÐÐͳһµ÷¶È¡£
### ĬÈϵ÷¶ÈÆ÷
```csharp
var timer = new TimerX(_ => { }, null, 1000, 5000);
timer.Scheduler; // TimerScheduler.Default
```
### ×Ô¶¨Òåµ÷¶ÈÆ÷
```csharp
// ´´½¨×¨Êôµ÷¶ÈÆ÷
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
}, null, 1000, 5000, "MyScheduler");
timer.Scheduler.Name; // "MyScheduler"
```
**ÊÊÓó¡¾°**£º
- ÐèÒª¶ÀÁ¢µÄµ÷¶ÈÏ̳߳Ø
- ¸ôÀ벻ͬҵÎñµÄ¶¨Ê±Æ÷
- ¿ØÖƲ»Í¬µ÷¶ÈÆ÷µÄÓÅÏȼ¶
---
## Á´Â·×·×Ù
TimerX ÄÚÖÃÁ´Â·×·×ÙÖ§³Ö£¬×Ô¶¯ÎªÃ¿´ÎÖ´Ðд´½¨ Span¡£
### ÉèÖÃ×·×ÙÆ÷
```csharp
using NewLife.Log;
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐ");
}, null, 1000, 5000)
{
Tracer = DefaultTracer.Instance, // ÉèÖÃ×·×ÙÆ÷
TracerName = "MyTask" // ×Ô¶¨ÒåÂñµãÃû³Æ
};
```
### ×·×ÙÊý¾Ý
ÿ´Î¶¨Ê±Æ÷´¥·¢£¬»á´´½¨Ò»¸ö Span£º
- **Ãû³Æ**£ºÄ¬ÈÏΪ `timer:{·½·¨Ãû}`£¬¿Éͨ¹ý `TracerName` ×Ô¶¨Òå
- **±êÇ©**£º¼Ç¼¶¨Ê±Æ÷ID¡¢ÖÜÆÚµÈÐÅÏ¢
- **ºÄʱ**£º¼Ç¼ÿ´Î»Øµ÷Ö´ÐеÄʱ¼ä
**²é¿´Í³¼Æ**£º
```
Tracer[timer:DoWork] Total=100 Errors=0 Speed=0.02tps Cost=150ms MaxCost=200ms MinCost=100ms
```
Ïê¼û£º[Á´Â·×·×ÙITracer](/NewLife/X/Blob/dev/Doc/tracer-Á´Â·×·×ÙITracer.md)
---
## ʹÓó¡¾°
### 1. ¶¨ÆÚÊý¾ÝÇåÀí
```csharp
// ÿÌìÁ賿3µãÇåÀí¹ýÆÚÊý¾Ý
var timer = new TimerX(state =>
{
var days = (Int32)state!;
var before = DateTime.Now.AddDays(-days);
var count = Database.Delete("WHERE CreateTime < @time", new { time = before });
Console.WriteLine($"ÇåÀíÁË {count} Ìõ¹ýÆÚÊý¾Ý");
}, 30, DateTime.Today.AddHours(3), 24 * 3600 * 1000);
```
### 2. ÐÄÌø¼ì²â
```csharp
var timer = new TimerX(_ =>
{
foreach (var client in clients)
{
if (client.LastActive.AddMinutes(5) < DateTime.Now)
{
Console.WriteLine($"¿Í»§¶Ë {client.Id} ³¬Ê±£¬¶Ï¿ªÁ¬½Ó");
client.Disconnect();
}
}
}, null, 0, 60000); // ÿ·ÖÖÓ¼ì²éÒ»´Î
```
### 3. ¶¨ÆÚÊý¾Ýͬ²½
```csharp
var timer = new TimerX(async _ =>
{
var data = await FetchDataFromApiAsync();
await SaveToDatabase(data);
Console.WriteLine("Êý¾Ýͬ²½Íê³É");
}, null, 0, 300000); // ÿ5·ÖÖÓͬ²½Ò»´Î
```
### 4. ¹¤×÷ÈÕ¶¨Ê±±¨±í
```csharp
// ÿ¸ö¹¤×÷ÈÕÔçÉÏ9µãÉú³É±¨±í
var timer = new TimerX(_ =>
{
var report = GenerateReport(DateTime.Today.AddDays(-1));
SendEmail(report);
Console.WriteLine("±¨±íÒÑ·¢ËÍ");
}, null, "0 0 9 * * 1-5");
```
### 5. ¶¨ÆÚ½¡¿µ¼ì²é
```csharp
var timer = new TimerX(_ =>
{
var healthy = CheckSystemHealth();
if (!healthy)
{
SendAlert("ϵͳÒì³£");
}
}, null, 0, 30000); // ÿ30Ãë¼ì²éÒ»´Î
```
---
## ×î¼Ñʵ¼ù
### 1. Òì²½»Øµ÷ÓÅÏÈ
¶ÔÓÚºÄʱ²Ù×÷£¬Ê¹ÓÃÒì²½»Øµ÷±ÜÃâ×èÈû£º
```csharp
// ÍÆ¼ö
var timer = new TimerX(async _ =>
{
await DoHeavyWorkAsync();
}, null, 0, 5000);
// ²»ÍƼö
var timer2 = new TimerX(_ =>
{
DoHeavyWork(); // ×èÈûÏß³Ì
}, null, 0, 5000);
```
### 2. Ö÷¶¯ÊÍ·Å×ÊÔ´
```csharp
public class MyService : IDisposable
{
private readonly TimerX _timer;
public MyService()
{
_timer = new TimerX(_ => DoWork(), null, 0, 5000);
}
public void Dispose()
{
_timer?.Dispose(); // ÊͷŶ¨Ê±Æ÷
}
}
```
### 3. ʹÓà Current ÊôÐÔ
Ôڻص÷ÖпÉÒÔ·ÃÎʵ±Ç°¶¨Ê±Æ÷£º
```csharp
var timer = new TimerX(_ =>
{
var current = TimerX.Current;
Console.WriteLine($"¶¨Ê±Æ÷[{current.Id}]µÚ{current.Timers}´ÎÖ´ÐÐ");
// ¶¯Ì¬µ÷ÕûÖÜÆÚ
if (current.Timers > 10)
current.Period = 10000;
}, null, 0, 5000);
```
### 4. ´íÎó´¦Àí
```csharp
var timer = new TimerX(_ =>
{
try
{
DoWork();
}
catch (Exception ex)
{
Console.WriteLine($"¶¨Ê±ÈÎÎñÒì³££º{ex.Message}");
// ¼Ç¼ÈÕÖ¾£¬²»ÒªÅ׳öÒì³£
}
}, null, 0, 5000);
```
### 5. Cron ¸´ÔÓ³¡¾°
```csharp
// ¹¤×÷ÈÕÔçÉÏ9µã£¬ÖÜÁùÔçÉÏ10µã
var crons = "0 0 9 * * 1-5;0 0 10 * * 6";
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö´ÐÐÈÎÎñ");
}, null, crons);
```
---
## ×¢ÒâÊÂÏî
### 1. ±ØÐëÖ÷¶¯ÊÍ·Å
```csharp
var timer = new TimerX(_ => { }, null, 0, 5000);
// ... ʹÓà ...
timer.Dispose(); // ±ØÐëµ÷Ó㬷ñÔòÄÚ´æÐ¹Â©
```
### 2. Delay ·½·¨µÄÏÝÚå
```csharp
// ´íÎó£ºtimer¿ÉÄܱ»GC»ØÊÕ
TimerX.Delay(_ => Console.WriteLine("Ö´ÐÐ"), 10000);
// ÕýÈ·£º±£³ÖÒýÓÃ
var timer = TimerX.Delay(_ => Console.WriteLine("Ö´ÐÐ"), 10000);
// ... ±£³ÖtimerÔÚ×÷ÓÃÓòÄÚ ...
```
### 3. ¾ø¶Ôʱ¼ä²»¿ÉÐÞ¸Ä
```csharp
var timer = new TimerX(_ => { }, null, DateTime.Today.AddHours(2), 86400000);
timer.SetNext(1000); // ÎÞЧ
timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5)); // ·µ»Ø false
```
### 4. State ÊÇÈõÒýÓÃ
```csharp
var obj = new MyObject();
var timer = new TimerX(_ =>
{
var state = _.State as MyObject; // ¿ÉÄÜΪ null
}, obj, 0, 5000);
// Èç¹û obj ±» GC »ØÊÕ£¬State »á±äΪ null
```
### 5. ÖÜÆÚΪ0Ö»Ö´ÐÐÒ»´Î
```csharp
var timer = new TimerX(_ =>
{
Console.WriteLine("Ö»Ö´ÐÐÒ»´Î");
}, null, 1000, 0); // Period=0£¬Ö»Ö´ÐÐÒ»´Î
```
---
## ³£¼ûÎÊÌâ
### 1. ¶¨Ê±Æ÷²»Ö´ÐУ¿
¼ì²é£º
- ÊÇ·ñ±» GC »ØÊÕ£¨±£³ÖÒýÓã©
- ÊÇ·ñÒÑ Dispose
- Period ÊÇ·ñΪ¸ºÊý
- Cron ±í´ïʽÊÇ·ñÕýÈ·
### 2. ¶¨Ê±Æ÷Ö´ÐÐÁ˶à´Î£¿
TimerX ÊDz»¿ÉÖØÈëµÄ£¬²»»á³öÏÖÕâ¸öÎÊÌâ¡£Èç¹û³öÏÖ£¬¼ì²éÊÇ·ñ´´½¨Á˶à¸ö¶¨Ê±Æ÷ʵÀý¡£
### 3. ÈçºÎÍ£Ö¹¶¨Ê±Æ÷£¿
```csharp
timer.Dispose(); // Ïú»Ù²¢ÒƳý
```
### 4. ÈçºÎÔÝÍ£ºÍ»Ö¸´£¿
```csharp
// ÔÝÍ££¨ÉèÖÃΪִֻÐÐÒ»´Î£©
timer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
// »Ö¸´
timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(5));
```
### 5. Cron ºÍ¾ø¶Ôʱ¼äµÄÇø±ð£¿
| ÌØÐÔ | Cron | ¾ø¶Ôʱ¼ä |
|-----|------|---------|
| ±í´ïʽ | Ö§³Ö¸´ÔÓ¹æÔò | ¹Ì¶¨Ê±¿Ì+ÖÜÆÚ |
| Áé»îÐÔ | ¸ß£¨Ãë¼¶¡¢ÐÇÆÚµÈ£© | µÍ£¨¹Ì¶¨ÖÜÆÚ£© |
| ÐÔÄÜ | ÂԵͣ¨Ðè½âÎö£© | ¸ß |
| ÊÊÓó¡¾° | ¸´ÔÓ¶¨Ê± | ¼òµ¥ÖÜÆÚ |
---
## ²Î¿¼×ÊÁÏ
- **Cron Îĵµ**: [cron-Cron±í´ïʽ.md](/NewLife/X/Blob/dev/Doc/cron-Cron±í´ïʽ.md)
- **Á´Â·×·×Ù**: [tracer-Á´Â·×·×ÙITracer.md](/NewLife/X/Blob/dev/Doc/tracer-Á´Â·×·×ÙITracer.md)
- **ÔÚÏßÎĵµ**: https://newlifex.com/core/timerx
- **Ô´Âë**: https://github.com/NewLifeX/X/blob/master/NewLife.Core/Threading/TimerX.cs
---
## ¸üÐÂÈÕÖ¾
- **2025-01**: ÍêÉÆÎĵµ£¬²¹³äÏêϸʾÀýºÍ×î¼Ñʵ¼ù
- **2024**: Ö§³Ö .NET 9.0£¬ÓÅ»¯ÐÔÄÜ
- **2023**: Ôö¼Ó Cron ¶à±í´ïʽ֧³Ö
- **2022**: Ôö¼ÓÒì²½»Øµ÷Ö§³Ö
- **2020**: ³õʼ°æ±¾£¬»ùÓÚ TickCount µÄ¾«×¼¼ÆÊ±
|