首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 中 System.Threading.Timer 被 IIS 釋放問題與 Quartz.net 解決方案

     編輯:關於ASP.NET

IIS 會自動回收非靜態物件,導致 System.Threading.Timer 在應用程式閒置時被釋放,定時任務中斷。解決關鍵在於將 Timer 參考保持在靜態變數,或改用成熟排程框架 Quartz.net。

問題重現與靜態變數解法

錯誤寫法:Timer 為區域變數,方法結束後被 GC 回收。

正確寫法(Global.asax):

public class Global : HttpApplication {
    private static Timer _timer;  // 靜態變數保持參考
    private static Log _log;

    protected void Application_Start(object sender, EventArgs e) {
        _log = new Log();
        _log.Write(ref _timer, 5000);  // 每 5 秒執行
    }
}

class Log {
    public void Write(ref Timer timer, int interval) {
        if (timer == null) {
            timer = new Timer(DoExecution, this, 0, interval);
        }
    }
    void DoExecution(object state) { /* 定時任務邏輯 */ }
}

Quartz.net 企業級解決方案(推薦)

Quartz.net 封裝排程複雜度,支援 Cron 運算式、叢集、持久化、監聽器等進階功能。

public class TimeJob : IJob {
    public void Execute(IJobExecutionContext context) {
        // 定時執行邏輯
    }
}

public class Global : HttpApplication {
    protected void Application_Start(object sender, EventArgs e) {
        // 定義工作
        IJobDetail job = JobBuilder.Create<TimeJob>()
            .WithIdentity("job1", "group1").Build();

        // 定義觸發器:每 5 秒
        ITrigger trigger = TriggerBuilder.Create()
            .WithIdentity("trigger1", "group1")
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever())
            .Build();

        // 啟動排程器
        ISchedulerFactory factory = new StdSchedulerFactory();
        IScheduler scheduler = factory.GetScheduler();
        scheduler.ScheduleJob(job, trigger);
        scheduler.Start();
    }
}

優勢比較

特性System.Threading.TimerQuartz.net
排程表達式僅固定間隔Cron、Calendar、簡單/複雜觸發
持久化不支援支援 ADO.NET JobStore
叢集支援無內建叢集鎖機制
監聽/攔截無JobListener、TriggerListener
錯誤處理自行 try-catch內建重試、誤火處理

生產環境強烈建議採用 Quartz.net 或 Hangfire 等成熟框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved