微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

线程执行超时处理、并发线程数控制

说明:这里限制了并发执行存储过程的最大个数,但并没有对并发线程数进行控制,与文章标题略有不符,但程序稍做改动即可控制并发线程数

 

需求及解决方案:

1、定时执行存储过程,如何判断执行时间已到,并且不能重复执行?

    不能用等于号判断时间相等,这样不太可靠,我采用的办法是用大于号判断,并且执行过后在数据库中记录一下,防止重复执行

2、如何限制同时执行的存储过程的个数?

    定义了一个静态变量,通过静态变量判断

 

代码

using System;
 System.Collections.Generic;
 System.ComponentModel;
 System.Configuration;
 System.Data;
 System.Data.OracleClient;
 System.Diagnostics;
 System.IO;
 System.ServiceProcess;
 System.Text;
 System.Threading;
 System.Timers;
 System.Xml;
 DBUtil;
 FQDService.DAL;
 FQDService.Models;
 FQDService.Utils;

namespace FQDService
{
    /// <summary>
    /// FQD服务
    </summary>
    partial class FQDService : ServiceBase
    {
        #region 变量
        <summary>
         执行存储过程线程数锁
        </summary>
        public static Object lockTreadCount = new Object();
         执行存储过程超时时间
        static int timeout = int.Parse(ConfigurationManager.AppSettings["Timeout"].Trim()) * 60 * 1000;
         等待执行存储过程时间间隔
        int interval =  执行存储过程最大数
        int maxRunProcCount = MaxRunProcCount 执行存储过程数
        int runProcCount = 0;
        #endregion

        #region 构造函数
        public FQDService()
        {
            InitializeComponent();
        }
        #region 启动
        protected override void OnStart(string[] args)
        {
            // Todo: 在此处添加代码以启动服务。
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Elapsed +=  System.Timers.ElapsedEventHandler(RunProc);
            timer.Start();
        }
        #region 结束
        void OnStop()
        {
             Todo: 在此处添加代码以执行停止服务所需的关闭操作。
        }
        #region 执行存储过程
         执行存储过程
        void RunProc(object sender,ElapsedEventArgs e)
        {
            try
            {
                Random rnd = new Random();
                List<RunTimeCfg> runTimeCfgList = RunTimeCfgDal.GetListAll();

                foreach (RunTimeCfg runTimeCfg in runTimeCfgList)  遍历Proc
                {
                    #region 判断是否到执行时间
                    bool run = false;
                    if (runTimeCfg.RunType == 1) 按天执行
                    {
                         今天没有执行过并且执行时间已到
                        if (DateTime.Now.Day != RunTimeCfgDal.GetLastRunTime(runTimeCfg.ProcName))
                        {
                            DateTime dtRunTime = DateTime.Parse(DateTime.Now.ToString(yyyy-MM-dd ") + runTimeCfg.RunTimeList[]);
                            if (DateTime.Now >= dtRunTime) run = true;
                        }
                    }
                    else 2) 按月执行
foreach (string runTime in runTimeCfg.RunTimeList)
                        {
                             今天是配置的日期并且今天没有执行过并且执行时间已到
                            int day = int.Parse(runTime.Split(' ')[if (DateTime.Now.Day != RunTimeCfgDal.GetLastRunTime(runTimeCfg.ProcName) && DateTime.Now.Day == day)
                            {
                                DateTime dtRunTime = DateTime.Parse(DateTime.Now.ToString(yyyy-MM-") + runTime);
                                ;
                            }
                        }
                    }
                    #endregion

                    if (run)
                    {
                        #region 执行
                        RunTimeCfgDal.SaveLastRunTime(runTimeCfg.ProcName); 更新最后执行时间
                        bool finish = false; 存储过程是否执行完毕
                        Thread thread = null;
                        thread = new Thread(new ParameterizedThreadStart(delegate( obj)
                        {
                            #region 等待执行存储过程
                            lock (lockTreadCount)
                            {
                                while (runProcCount >= maxRunProcCount)
                                {
                                    Thread.Sleep(interval);
                                }
                                runProcCount++;
                            }
                            #endregion

                            #region 执行存储过程超时处理
                            Thread threadTimer =  obj2)
                            {
                                Thread.Sleep(timeout);
                                if (finish == )
                                {
                                    FileLogger.WriteLog(string.Format(存储过程{0}执行超时",runTimeCfg.ProcName));
                                    if (thread != )
                                    {
                                        
                                        {
                                            thread.Abort();
                                        }
                                        catch (Exception ex)
                                        {
                                            FileLogger.WriteErrorLog(存储过程{0}终止线程出错:{1}#region 为执行存储过程准备参数
                            OracleParameter[] oracleParams = new OracleParameter[2];
                            oracleParams[0] = new OracleParameter(runTypearams[1] = cutTimearams[0].Value = 1;
                            oracleParams[1].Value = DateTime.Now.Date;
                            
                            {
                                
                                {
                                    #region 执行存储过程
                                    FileLogger.WriteLog(开始执行存储过程{0}执行存储过程
                                    OracleHelper.RunProcedure(runTimeCfg.ProcName,oracleParams);

                                    模拟执行存储过程
                                    Thread.Sleep(rnd.Next(100,1900));
存储过程{0}执行成功;
                                    #endregion
                                }
                                 (Exception ex)
                                {
                                    #region 执行存储过程失败日志
                                    StringBuilder sbParams =  StringBuilder();
                                    foreach (OracleParameter oracleParam  oracleParams)
                                    {
                                        sbParams.Append({0}:{1},aram.ParameterName,oracleParam.Value.ToString()));
                                    }
                                    string strParams = ""if (sbParams.Length > 0) strParams = sbParams.ToString(0,sbParams.Length - );
                                    FileLogger.WriteErrorLog(存储过程执行失败{0}({1}):{2}arams,ex.Message));
                                    
                                }
                            }
                            捕获线程终止异常
                            }
                            finally
                            {
                                runProcCount--;
                            }
                        }));
                        thread.Start();
                        
                    }
                }
            }
             (Exception ex)
            {
                FileLogger.WriteErrorLog(ex.Message);
            }
        }
        

    }
}
View Code

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐