1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      怎么在AspNetCore中實現(xiàn)一個web定時任務(wù)-創(chuàng)新互聯(lián)

      這篇文章將為大家詳細講解有關(guān)怎么在AspNet Core中實現(xiàn)一個web定時任務(wù),文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

      創(chuàng)新互聯(lián)是一群有想法、有熱情,對互聯(lián)網(wǎng)抱有執(zhí)著信念的年輕人,愿用自己的智慧和熱情,幫助您使用好互聯(lián)網(wǎng)工具,成為您的建站英雄,成為您網(wǎng)站制作和網(wǎng)絡(luò)營銷的“秘密武器”,專注于網(wǎng)站策劃、備案、域名申請、設(shè)計、后臺開發(fā)、關(guān)鍵詞優(yōu)化排名、運營管理、維護服務(wù)、微信網(wǎng)站、成都做手機網(wǎng)站,網(wǎng)站上線不是大家合作的終結(jié),相反,網(wǎng)站維護才剛剛開始,我們期待常年累月的網(wǎng)站運行過程總著為您提供更多的支持。我們致力于解決問題,創(chuàng)造價值,不推諉,主動承擔。

      項目背景


      采用redis計數(shù),設(shè)定每小時將當日累積數(shù)據(jù)持久化到關(guān)系型數(shù)據(jù)庫sqlite。

      添加Quartz.Net Nuget 依賴包:


      • ①.定義定時任務(wù)內(nèi)容: Job

      • ②.設(shè)置觸發(fā)條件: Trigger

      • ③.將Quartz.Net集成進AspNet Core

      頭腦風暴

      IScheduler類包裝了上述背景需要完成的第①②點工作 ,SimpleJobFactory定義了生成指定的Job任務(wù)的過程,這個行為是利用反射機制調(diào)用無參構(gòu)造函數(shù)構(gòu)造出的Job實例。下面是源碼:

      //----------------選自Quartz.Simpl.SimpleJobFactory類-------------
      using System;
      using Quartz.Logging;
      using Quartz.Spi;
      using Quartz.Util;
      namespace Quartz.Simpl
      {
       ///  
       /// The default JobFactory used by Quartz - simply calls 
       ///  on the job class.
       /// 
       /// 
       /// 
       /// James House
       /// Marko Lahma (.NET)
       public class SimpleJobFactory : IJobFactory
       {
        private static readonly ILog log = LogProvider.GetLogger(typeof (SimpleJobFactory));
      
        /// 
        /// Called by the scheduler at the time of the trigger firing, in order to
        /// produce a  instance on which to call Execute.
        /// 
        /// 
        /// It should be extremely rare for this method to throw an exception -
        /// basically only the case where there is no way at all to instantiate
        /// and prepare the Job for execution. When the exception is thrown, the
        /// Scheduler will move all triggers associated with the Job into the
        ///  state, which will require human
        /// intervention (e.g. an application restart after fixing whatever
        /// configuration problem led to the issue with instantiating the Job).
        /// 
        /// The TriggerFiredBundle from which the 
        /// and other info relating to the trigger firing can be obtained.
        /// 
        /// the newly instantiated Job
        ///  SchedulerException if there is a problem instantiating the Job. 
        public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
         IJobDetail jobDetail = bundle.JobDetail;
         Type jobType = jobDetail.JobType;
         try
         {
          if (log.IsDebugEnabled())
          {
           log.Debug($"Producing instance of Job '{jobDetail.Key}', class={jobType.FullName}");
          }
      
          return ObjectUtils.InstantiateType(jobType);
         }
         catch (Exception e)
         {
          SchedulerException se = new SchedulerException($"Problem instantiating class '{jobDetail.JobType.FullName}'", e);
          throw se;
         }
        }
      
        /// 
        /// Allows the job factory to destroy/cleanup the job if needed. 
        /// No-op when using SimpleJobFactory.
        /// 
        public virtual void ReturnJob(IJob job)
        {
         var disposable = job as IDisposable;
         disposable?.Dispose();
        }
       }
      }
      
      //------------------節(jié)選自Quartz.Util.ObjectUtils類-------------------------
       public static T InstantiateType(Type type)
      {
        if (type == null)
        {
         throw new ArgumentNullException(nameof(type), "Cannot instantiate null");
        }
        ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
        if (ci == null)
        {
         throw new ArgumentException("Cannot instantiate type which has no empty constructor", type.Name);
        }
        return (T) ci.Invoke(new object[0]);
      }

      很多時候,定義的Job任務(wù)依賴了其他組件,這時默認的SimpleJobFactory不可用, 需要考慮將Job任務(wù)作為依賴注入組件,加入依賴注入容器。

      關(guān)鍵思路:

      ①. IScheduler 開放了JobFactory 屬性,便于你控制Job任務(wù)的實例化方式;

      JobFactories may be of use to those wishing to have their application produce IJob instances via some special mechanism, such as to give the opportunity for dependency injection
      ②. AspNet Core的服務(wù)架構(gòu)是以依賴注入為基礎(chǔ)的,利用AspNet Core已有的依賴注入容器IServiceProvider管理Job 服務(wù)的創(chuàng)建過程。

      編碼實踐

      ① 定義Job內(nèi)容:

      // -------每小時將redis數(shù)據(jù)持久化到sqlite, 每日凌晨跳針,持久化昨天全天數(shù)據(jù)---------------------
      public class UsageCounterSyncJob : IJob
      {
        private readonly EqidDbContext _context;
        private readonly IDatabase _redisDB1;
        private readonly ILogger _logger;
        public UsageCounterSyncJob(EqidDbContext context, RedisDatabase redisCache, ILoggerFactory loggerFactory)
        {
         _context = context;
         _redisDB1 = redisCache[1];
         _logger = loggerFactory.CreateLogger();
        }
         public async Task Execute(IJobExecutionContext context)
        {
         // 觸發(fā)時間在凌晨,則同步昨天的計數(shù)
         var _day = DateTime.Now.ToString("yyyyMMdd");
         if (context.FireTimeUtc.LocalDateTime.Hour == 0)
          _day = DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
      
         await SyncRedisCounter(_day);
         _logger.LogInformation("[UsageCounterSyncJob] Schedule job executed.");
        }
        ......
       }

      ②注冊Job和Trigger:

      namespace EqidManager
      {
       using IOCContainer = IServiceProvider;
       // Quartz.Net啟動后注冊job和trigger
       public class QuartzStartup
       {
        public IScheduler _scheduler { get; set; }
      
        private readonly ILogger _logger;
        private readonly IJobFactory iocJobfactory;
        public QuartzStartup(IOCContainer IocContainer, ILoggerFactory loggerFactory)
        {
         _logger = loggerFactory.CreateLogger();
         iocJobfactory = new IOCJobFactory(IocContainer);
         var schedulerFactory = new StdSchedulerFactory();
         _scheduler = schedulerFactory.GetScheduler().Result;
         _scheduler.JobFactory = iocJobfactory;
        }
      
        public void Start()
        {
         _logger.LogInformation("Schedule job load as application start.");
         _scheduler.Start().Wait();
      
         var UsageCounterSyncJob = JobBuilder.Create()
          .WithIdentity("UsageCounterSyncJob")
          .Build();
      
         var UsageCounterSyncJobTrigger = TriggerBuilder.Create()
          .WithIdentity("UsageCounterSyncCron")
          .StartNow()
          // 每隔一小時同步一次
          .WithCronSchedule("0 0 * * * ?")  // Seconds,Minutes,Hours,Day-of-Month,Month,Day-of-Week,Year(optional field)
          .Build();
         _scheduler.ScheduleJob(UsageCounterSyncJob, UsageCounterSyncJobTrigger).Wait();
      
         _scheduler.TriggerJob(new JobKey("UsageCounterSyncJob"));
        }
      
        public void Stop()
        {
         if (_scheduler == null)
         {
          return;
         }
      
         if (_scheduler.Shutdown(waitForJobsToComplete: true).Wait(30000))
          _scheduler = null;
         else
         {
         }
         _logger.LogCritical("Schedule job upload as application stopped");
        }
       }
      
       /// 
       /// IOCJobFactory :實現(xiàn)在Timer觸發(fā)的時候注入生成對應(yīng)的Job組件
       /// 
       public class IOCJobFactory : IJobFactory
       {
        protected readonly IOCContainer Container;
      
        public IOCJobFactory(IOCContainer container)
        {
         Container = container;
        }
      
        //Called by the scheduler at the time of the trigger firing, in order to produce
        //  a Quartz.IJob instance on which to call Execute.
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
         return Container.GetService(bundle.JobDetail.JobType) as IJob;
        }
      
        // Allows the job factory to destroy/cleanup the job if needed.
        public void ReturnJob(IJob job)
        {
        }
       }
      }

      ③結(jié)合ASpNet Core 注入組件;綁定Quartz.Net

      //-------------------------------截取自Startup文件------------------------
      ......
      services.AddTransient();  // 這里使用瞬時依賴注入
      services.AddSingleton();
      ......
      
      // 綁定Quartz.Net
      public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IApplicationLifetime lifetime, ILoggerFactory loggerFactory)
      {
        var quartz = app.ApplicationServices.GetRequiredService();
        lifetime.ApplicationStarted.Register(quartz.Start);
        lifetime.ApplicationStopped.Register(quartz.Stop);
      }

      附:IIS 網(wǎng)站低頻訪問導(dǎo)致工作進程進入閑置狀態(tài)的 解決辦法

      IIS為網(wǎng)站默認設(shè)定了20min閑置超時時間:20分鐘內(nèi)沒有處理請求、也沒有收到新的請求,工作進程就進入閑置狀態(tài)。


      IIS上低頻web訪問會造成工作進程關(guān)閉,此時應(yīng)用程序池回收,Timer等線程資源會被銷毀;當工作進程重新運作,Timer可能會重新生成起效, 但我們的設(shè)定的定時Job可能沒有按需正確執(zhí)行。

      怎么在AspNet Core中實現(xiàn)一個web定時任務(wù)

      故為在IIS網(wǎng)站實現(xiàn)低頻web訪問下的定時任務(wù):


      設(shè)置了Idle TimeOut =0;同時將【應(yīng)用程序池】->【正在回收】->不勾選【回收條件】

      關(guān)于怎么在AspNet Core中實現(xiàn)一個web定時任務(wù)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


      本文名稱:怎么在AspNetCore中實現(xiàn)一個web定時任務(wù)-創(chuàng)新互聯(lián)
      轉(zhuǎn)載注明:http://www.ef60e0e.cn/article/epeeg.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        邯郸县| 镇巴县| 吉林市| 同心县| 太白县| 克拉玛依市| 修水县| 汶上县| 昭苏县| 横峰县| 东乡| 东丽区| 阳春市| 南城县| 平山县| 扎鲁特旗| 上蔡县| 甘肃省| 新营市| 弋阳县| 绵阳市| 迁安市| 新巴尔虎右旗| 汝城县| 湟源县| 托克托县| 中方县| 红原县| 沙田区| 昌吉市| 临沂市| 合作市| 岳阳县| 锡林浩特市| 武清区| 嘉黎县| 南通市| 南和县| 武强县| 长顺县| 安化县|