龟叔啊 2023-03-03 09:10 采纳率: 50%
浏览 72
已结题

asp.net 定时任务和IIS程序池的配置

ASP.NET 项目中3个定时任务,其中有一个任务经常莫名奇妙的没有运行,其他两个任务运行正常。
定时任务业务逻辑是:每日在固定时间范围内(例如:22:00~23:00)进行考勤统计,统计后将结果发送微信消息给管理员。
没有运行有两种情况:1.完全没有Timer的时间处理程序(日志中没有记录下面代码中的“开始生成考勤策略”字样)。2.运行了统计逻辑但没有发送微信消息(未收到微信消息,也没有微信发送失败的相关错误日志)。主要代码如下

//程序启动
 protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            //WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            try
            {
                LogFile.WriteError(DateTime.Now + ":服务启动。");
                //== 考勤策略生成服务
                var checkWorkInterval = double.Parse((CachedConfigContext.Current.CheckWorkConfig.Interval * 1000).ToString());
                Timer checkWorTime = new Timer(checkWorkInterval);
                checkWorTime.Elapsed += new System.Timers.ElapsedEventHandler(CheckWorkEvent);
                checkWorTime.AutoReset = true;
                checkWorTime.Enabled = Convert.ToBoolean(CachedConfigContext.Current.CheckWorkConfig.MasterSwitch);
            }
            catch (Exception ex)
            {
                LogFile.WriteError(DateTime.Now + ";服务发生错误:" + ex.ToString());
            }
        }
        //IIS休眠或结束时重新唤醒
        protected void Application_End()
        {
            /*防止定时器失效*/
            LogFile.WriteError("触发Application_End方法");
            System.Threading.Thread.Sleep(5000);
            string strUrl = "http://" + Application["WebApiUri_Authority"].ToString() + "/api/Msg/Post";

            string strRec = HttpClientHelper.PostData("", strUrl, "", "", HttpClientHelper.PostContentType.JSON);
        }
        /// <summary>
        /// 每日考勤策略生成事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckWorkEvent(object sender, ElapsedEventArgs e)
        {
            var time = (Timer)sender;
            DateTime nowDate = DateTime.Now;//当前时间
            try
            {
                DateTime startDate =CachedConfigContext.Current.CheckWorkConfig.StartTime;//22:00
                DateTime endDate =CachedConfigContext.Current.CheckWorkConfig.EndTime;//23:00
                if (startDate <= nowDate && nowDate <= endDate)
                {
                    time.Stop();
                    LogFile.WriteError(DateTime.Now + ":开始生成考勤策略");
                    //生成考勤策略
                    var count = checkworkBll.CheckWorkCreate();//具体的业务逻辑
                    LogFile.WriteError(DateTime.Now + ":共生成" + count + "条考勤策略");
                    LogFile.WriteError(DateTime.Now + ":生成考勤策略结束");
                    time.Start();
                }//判断是否在固定时间范围内
            }
            catch (Exception ex)
            {
                LogFile.WriteError(DateTime.Now + ":生成策略错误:" + ex.ToString());
                time.Start();
            }
        }

每次任务停止后,我尝试重启程序就恢复正常,两天后又停止了,因为以前没有出现过该问题,于是我回想了最近做过的改动,曾经配置过IIS程序池将启动模式从“OnDemand”改为“AlwaysRunning”,同时将进程模型中的闲置时间20分钟改为0,再没有任何头绪的情况下,我尝试改回原先的配置后,竟然正常了。

img

img

我的问题是:IIS程序池的配置为什么会影响?是什么原理?请哪位有经验的朋友帮助解惑下,谢谢!
程序运行的环境是:操作系统windows server 2012 iis 8.0 .net4.5

  • 写回答

8条回答 默认 最新

  • 社区专家-Monster-XH 2023-03-03 09:54
    关注

    基于Monster 组和GPT的调写:
    两个影响因素:System.Timers.Timer 类和 IIS 应用程序池

    • 你的定时任务的代码实现中使用了 System.Timers.Timer 类。这个类在 ASP.NET 应用程序中使用时,需要特别小心,因为它的工作方式与 ASP.NET 运行的线程池机制不兼容,可能会导致定时任务不准确或停止工作。
    • 另外,在 IIS 中对应用程序池的设置进行了更改,将启动模式从 "OnDemand" 更改为 "AlwaysRunning",并将进程模型中的空闲时间从 20 分钟更改为 0。这些更改可以影响应用程序池的行为,导致它更积极地保持应用程序处于运行状态,从而确保您的定时任务正常工作。
    • 具体地说,如果应用程序池的启动模式为 "AlwaysRunning",则 IIS 将在应用程序池的第一个请求到达之前启动应用程序,并将其保持运行状态,直到应用程序池被停止或 IIS 服务关闭。这有助于确保您的定时任务能够在预期的时间内启动和运行。
    • 另一方面,如果进程模型中的空闲时间为 0,则 IIS 将不会在应用程序空闲时回收应用程序池中的工作进程。这意味着你的定时任务将始终处于运行状态,而不会被 IIS 中止或回收。
    • 总之,你的定时任务可能受到 System.Timers.Timer 类和 IIS 应用程序池设置之间的交互影响。为了确保你的定时任务始终正常工作,建议你使用更可靠的定时任务实现方式,例如使用 Windows 服务或使用基于 Quartz.NET 等第三方库的任务调度程序。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 系统已结题 3月12日
  • 已采纳回答 3月4日
  • 修改了问题 3月3日
  • 创建了问题 3月3日

悬赏问题

  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法