本文实例讲述了C#线程执行超时处理与并发线程数控制的方法。分享给大家供大家参考。具体实现方法如下:
特别说明:
1、为了测试方便,这里对存储过程的执行是模拟的
2、这里限制了并发执行存储过程的最大个数,但并没有对并发线程数进行控制,与文章标题略有不符,但程序稍做改动即可控制并发线程数
代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.OracleClient; using System.Diagnostics; using System.IO; using System.ServiceProcess; using System.Text; using System.Threading; using System.Timers; using System.Xml; using DBUtil; using FQDService.Utils;namespace FQDService { /// <summary> /// FQD服务 /// </summary> partial class FQDService : ServiceBase { #region 变量 /// <summary> /// 存储过程配置文档 /// </summary> public static XmlDocument doc; /// <summary> /// 执行存储过程线程数锁 /// </summary> public static Object lockTreadCount = new Object(); /// <summary> /// 执行存储过程超时时间 /// </summary> public static int timeout = 1000; /// <summary> /// 等待执行存储过程时间间隔 /// </summary> public static int interval = 100; /// <summary> /// 执行存储过程最大数 /// </summary> public static int maxRunProcCount = 5; /// <summary> /// 执行存储过程数 /// </summary> public static int runProcCount = 0; #endregion
#region 构造函数 public FQDService() { InitializeComponent(); } #endregion
#region 启动 protected override void OnStart(string[] args) { // TODO: 在此处添加代码以启动服务。 doc = XMLHelper.GetXmlDocument(); System.Timers.Timer timer = new System.Timers.Timer(60 * 1000); timer.Elapsed += new System.Timers.ElapsedEventHandler(RunProc); timer.Start(); } #endregion
#region 结束 protected override void OnStop() { // TODO: 在此处添加代码以执行停止服务所需的关闭操作。 } #endregion
#region 执行存储过程 /// <summary> /// 执行存储过程 /// </summary> public void RunProc(object sender, ElapsedEventArgs e) { try { Random rnd = new Random(); XmlNode rootNode = doc.SelectSingleNode("settings");
foreach (XmlNode procNode in rootNode.ChildNodes) // 遍历Proc { string procName = procNode.SelectSingleNode("Name").InnerText.Trim(); string runTime = procNode.SelectSingleNode("RunTime").InnerText.Trim();
if (DateTime.Now.ToString("HH:mm") == "14:55") { bool finish = false; //存储过程是否执行完毕 Thread thread = null; thread = new Thread(new ParameterizedThreadStart(delegate(object obj) { #region 等待执行存储过程 lock (lockTreadCount) { while (runProcCount >= maxRunProcCount) { Thread.Sleep(interval); } runProcCount++; } #endregion
#region 执行存储过程超时处理 Thread threadTimer = new Thread(new ParameterizedThreadStart(delegate(object obj2) { Thread.Sleep(timeout); if (finish == false) { FileLogger.WriteLog(string.Format("存储过程{0}执行超时", procName)); if (thread != null) { try { thread.Abort(); } catch (Exception ex) { FileLogger.WriteErrorLog(string.Format("存储过程{0}终止线程出错:{1}", procName, ex.Message)); } } } })); threadTimer.Start(); #endregion
#region 为执行存储过程准备参数 XmlNodeList paramList = procNode.SelectSingleNode("Params").ChildNodes; OracleParameter[] oracleParams = new OracleParameter[paramList.Count]; for (int i = 0; i < paramList.Count; i++) // 遍历param { XmlNode paramNode = paramList[i]; string paramName = paramNode.SelectSingleNode("Name").InnerText.Trim(); string paramType = paramNode.SelectSingleNode("Type").InnerText.Trim(); string paramValue = paramNode.SelectSingleNode("Value").InnerText.Trim();
oracleParams[i] = new OracleParameter(paramName, Enum.Parse(typeof(OracleType), paramType)); if ((OracleType)Enum.Parse(typeof(OracleType), paramType) == OracleType.DateTime) { DateTime now = DateTime.Now; string[] paramValueArray = paramValue.Split(':'); oracleParams[i].Value = new DateTime(now.Year, now.Month, now.Day, int.Parse(paramValueArray[0]), int.Parse(paramValueArray[1]), int.Parse(paramValueArray[2])); } else { oracleParams[i].Value = paramValue; } } #endregion
try { try { #region 执行存储过程 FileLogger.WriteLog(string.Format("开始执行存储过程{0}", procName));
//执行存储过程 //OracleHelper.RunProcedure(procName, oracleParams);
//模拟执行存储过程 Thread.Sleep(rnd.Next(100, 1900));
FileLogger.WriteLog(string.Format("存储过程{0}执行成功", procName)); finish = true; #endregion } catch (Exception ex) { #region 执行存储过程失败日志 StringBuilder sbParams = new StringBuilder(); foreach (OracleParameter oracleParam in oracleParams) { sbParams.Append(string.Format("{0}:{1},", oracleParam.ParameterName, oracleParam.Value.ToString())); } string strParams = ""; if (sbParams.Length > 0) strParams = sbParams.ToString(0, sbParams.Length - 1); FileLogger.WriteErrorLog(string.Format("存储过程执行失败{0}({1}):{2}", procName, strParams, ex.Message)); #endregion } } catch { //捕获线程终止异常 } finally { runProcCount--; } })); thread.Start(); } } } catch (Exception ex) { FileLogger.WriteErrorLog(ex.Message); } } #endregion
} }
希望本文所述对大家的C#程序设计有所帮助。
想象一个超标量(多个执行单元)并且还支持超线程(SMT)的CPU(或内核)。 为什么CPU可以真正并行执行的软件线程数通常由它拥有的逻辑内核(即所谓的硬件线程)的数量给出,而不是它拥有的执行单元总数? 如果我的理解是正确的,SMT实际上并没有实现真正的并行执行,它只是通过复制CPU的某些部分(存储架构状态的部分,但不是主要执行资源)来使上下文切换更快/更有效。另一方面,超标量架构允许每个时钟周期真
并发是什么?引用Rob Pike的经典描述: 并发是同一时间应对多件事情的能力 其实在我们身边就有很多并发的事情,比如一边上课,一边发短信;一边给小孩喂奶,一边看电视,只要你细心留意,就会发现许多类似的事。相应地,在软件的世界里,我们也会发现这样的事,比如一边写博客,一边听音乐;一边看网页,一边下载软件等等。显而易见这样会节约不少时间,干更多的事。然而一开始计算机系统并不能同时处理两件事,这明显满
启动并行处理最简单的方式就是在 Step 配置中加上一个TaskExecutor , 比如,作为 tasklet 的一个属性: <step id="loading"> <tasklet task-executor="taskExecutor">...</tasklet> </step> 上面的示例中, taskExecutor指向了另一个实现 TaskExecutor 接口的Bean. T
这种方法的Java博士说 如果需要,最多等待给定的时间完成计算,然后检索其结果(如果可用)。 参数: 超时等待的最长时间 unit超时参数的时间单位 根据我的理解,我们对强加了一个超时,我们提交给,这样,我的将在指定的时间(超时)过去后中断 但是根据下面的代码,似乎超过了超时时间(2秒),我真的很难理解这一点。谁能给我指一下正确的路吗?
问题内容: 根据我一直在阅读的定义: 线程基本上是并发(同时)运行的代码段 。 但是,如何在存在线程调度程序的情况下同时运行它们? 我读到,线程调度程序基本上是从线程池中随机选择一个线程在某个时刻运行。从中我得到一个确切的时间点,只有一个可运行线程真正处于运行状态(运行)。( 所有这些均来自SCJP Sun认证程序员学习指南 )有人可以澄清吗? 这些线程是否真正同时运行? 问题答案: 但是,如何在
除了接口比普通线程(例如管理)有一些优势之外,执行以下操作之间是否存在真正的内部差异(性能差异大、资源消耗……): 以及: 我只问这里的一个线索。