• C# Quartz 整理


    因项目需要,在C#中使用了定时程序。自然就使用了Quartz了

    但是使用的时候,经过一段时间后,发现了两个重大问题,结果导致的是一样的,就是都导致了定时不会继续执行了。

    第一个问题是,定时程序发布在IIS下,但是IIS自己本身是有回收机制的,然后如果到了晚上,没人操作后台了,那么IIS会自动回收定时程序。

    这里可以通过代码层面解决,就是说让IIS一直处于被使用状态,自然就不会回收了。

    具体的代码改动是:

    在项目中的Global.asax文件里,增加一段

    protected void Application_End(object sender, EventArgs e)
            {
                // 在应用程序关闭时运行的代码   
                //解决应用池回收问题   
                System.Threading.Thread.Sleep(5000);
                string strUrl = ProjectPara.ProPath;
                System.Net.HttpWebRequest _HttpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUrl);
                System.Net.HttpWebResponse _HttpWebResponse = (System.Net.HttpWebResponse)_HttpWebRequest.GetResponse();
                System.IO.Stream _Stream = _HttpWebResponse.GetResponseStream();//得到回写的字节流   
            }

    这个的方法触发的节点是应用程序关闭的时候会执行此方法,目的是通过HttpWebRequest发送一次请求,然后得到返回的字节流,这样每次应用程序关闭了,都会请求一次,就很好的阻止了IIS的回收。

    还有一个问题是,定时程序执行中,如果程序中抛异常了,那么也会导致定时失效,原因是出现了异常,在代码中有处理,如果出现异常,直接停掉定时任务

    public virtual void Execute(IJobExecutionContext context)
            {
                ValidationErrors validationErrors = new ValidationErrors();
                //取状态值
                JobDataMap dataMap = context.JobDetail.JobDataMap;
                string id = dataMap.GetString(ID);//任务ID
                string taskName = dataMap.GetString(TASKNAME);//任务名称
                //
                JobKey jobKey = context.JobDetail.Key;
                string jobName = jobKey.Name;//任务名称=任务名称+任务ID
                try
                {
                    //开始执行业务逻辑
                    Log.Write(jobName, "开始任务>>>>>>" + jobName, "成功");
                    //取当前程序集
                    Assembly assem = Assembly.GetExecutingAssembly();
                    //创建任务对象并执行
                    Object o = assem.CreateInstance(taskName, false,
                        BindingFlags.ExactBinding,
                        null, new Object[] { }, null, null);
                    MethodInfo m = assem.GetType(taskName).GetMethod("RunJob");//默认调用方法
                    Object ret = m.Invoke(o, new Object[] { dataMap, jobName, id, taskName });
                    //更新任务状态
                    TaskJob.UpdateState(ref validationErrors, jobName, 1, ret.ToString());
                    //////////////////////////////////////////////////////////////////
                    if (validationErrors.Count > 0)
                    {
                        Log.Write(jobName, "Error", validationErrors.Error);
                    }
                    Log.Write(jobName, "<<<<<<<结束任务" + jobName, "成功");
                }
                catch (System.Exception e)
                {
                    Log.Write(jobName, "Exception", e.Message);
                    JobExecutionException e2 = new JobExecutionException(e);
                    e2.UnscheduleAllTriggers = true;
                    throw e2;
                }
            }

    但是并不是所有情况都需要出现异常了,就停掉trigger,可以继续执行下次,所以注视掉这句即可。

    这里引申一个问题,因为定时是invoke调用的,这个方法会忽略掉内部方法的catch,直接在当前invoke中捕获。

    所以这里处理下即可。

  • 相关阅读:
    location.replace与location.href,location.reload的区别
    JavaScript 中 this 的用法
    setTimeout 的用法
    ngRoute 和 ui.router 的使用方法和区别
    js正则匹配只能输入有效数字可加小数点
    正则表达式
    关于浮动与清除浮动
    当给一个元素的宽度设置为百分比的时候,百分比的计算值是由它的直接父级元素的宽度决定
    内联(行级)元素不能设置margin-top
    JS判断数据是否是JSON类型
  • 原文地址:https://www.cnblogs.com/Rexcnblog/p/9340607.html
Copyright © 2020-2023  润新知