C#线程执行超时处理与并发线程数控制实例

本文实例讲述了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#程序设计有所帮助。

时间: 2014-11-01

C#实现的Win32控制台线程计时器功能示例

本文实例讲述了C#实现的Win32控制台线程计时器功能.分享给大家供大家参考,具体如下: 在C#中提供了三种类型的计时器: 1.基于 Windows 的标准计时器(System.Windows.Forms.Timer) 2.基于服务器的计时器(System.Timers.Timer) 3.线程计时器(System.Threading.Timer) 一.基于 Windows 的标准计时器(System.Windows.Forms.Timer) 首先注意一点就是:Windows 计时器是为单线程环境

C#实现控制线程池最大数并发线程

1. 实验目的: 使用线程池的时候,有时候需要考虑服务器的最大线程数目和程序最快执行所有业务逻辑的取舍. 并非逻辑线程越多也好,而且新的逻辑线程必须会在线程池的等待队列中等待 ,直到线程池中工作的线程执行完毕, 才会有系统线程取出等待队列中的逻辑线程,进行CPU运算. 2.  解决问题: <a>如果不考虑服务器实际可支持的最大并行线程个数,程序不停往线程池申请新的逻辑线程,这个时候我们可以发现CPU的使用率会不断飙升,并且内存.网络带宽占用也会随着逻辑线程在CPU队列中堆积,而不断增大. &l

C#控制台下测试多线程的方法

本文实例讲述了C#控制台下多线程实现方法.分享给大家供大家参考.具体如下: class Program { static void Main(string[] args) { ThreadStart num = new ThreadStart(PrintNum); Thread ConstrolNum = new Thread(num); ThreadStart str = new ThreadStart(PrintStr); Thread ConstrolStr = new Thread(st

C#多线程之线程控制详解

本文为大家分享了C#多线程之线程控制,供大家参考,具体内容如下 方案一: 调用线程控制方法.启动:Thread.Start();停止:Thread.Abort();暂停:Thread.Suspend();继续:Thread.Resume(); private void btn_Start_Click(object sender, EventArgs e) { mThread.Start(); // 开始 } private void btn_Stop_Click(object sender, E

C#通过Semaphore类控制线程队列的方法

本文实例讲述了C#通过Semaphore类控制线程队列的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Diagnostics; using System.Threading; using System.ComponentModel; using System.Col

Java使用阻塞队列控制线程通信的方法实例详解

本文实例讲述了Java使用阻塞队列控制线程通信的方法.分享给大家供大家参考,具体如下: 一 点睛 阻塞队列主要用在生产者/消费者的场景,下面这幅图展示了一个线程生产.一个线程消费的场景: 负责生产的线程不断的制造新对象并插入到阻塞队列中,直到达到这个队列的上限值.队列达到上限值之后生产线程将会被阻塞,直到消费的线程对这个队列进行消费.同理,负责消费的线程不断的从队列中消费对象,直到这个队列为空,当队列为空时,消费线程将会被阻塞,除非队列中有新的对象被插入. BlockingQueue的核心方法:

java线程池:获取运行线程数并控制线程启动速度的方法

在java里, 我们可以使用Executors.newFixedThreadPool 来创建线程池, 然后就可以不停的创建新任务,并用线程池来执行了. 在提交任务时,如果线程池已经被占满,任务会进到一个队列里等待执行. 这种机制在一些特定情况下会有些问题.今天我就遇到一种情况:创建线程比线程执行的速度要快的多,而且单个线程占用的内存又多,所以很快内存就爆了. 想了一个办法,就是在提交任务之前,先检查目前正在执行的线程数目,只有没把线程池占满的时候在去提交任务. 代码很简单: int thread

Java使用Condition控制线程通信的方法实例详解

本文实例讲述了Java使用Condition控制线程通信的方法.分享给大家供大家参考,具体如下: 一 点睛 当使用Lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到Lock对象.却无法继续执行的线程释放Lock对象,Condtion对象也可以唤醒其他处于等待的线程. Condition 将同步监视锁方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与Lock对象组合使用,为每个对象提供多

iOS应用程序中通过dispatch队列控制线程执行的方法

GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合block实现的GCD,把函数闭包(Closure)的特性发挥得淋漓尽致. dispatch队列的生成可以有这几种方式: 1. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_

利用ace的ACE_Task等类实现线程池的方法详解

本代码应该是ace自带的例子了,但是我觉得是非常好的,于是给大家分享一下.注释非常详细啊.头文件 复制代码 代码如下: #ifndef THREAD_POOL_H#define THREAD_POOL_H/* In order to implement a thread pool, we have to have an object that   can create a thread.  The ACE_Task<> is the basis for doing just   such a

Java编程中实现Condition控制线程通信

java中控制线程通信的方法 1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Condition控制线程通信,灵活. 3.利用管道pipe进行线程通信,不推荐 4.利用BlockingQueue控制线程通信 本文就讲解利用Condition控制线程通信,非常灵活的方式. Condition类是用来保持Lock对象的协调调用. 对Lock不了解的可以参考:Java线程同步Lock同步锁代码示例

Java中使用阻塞队列控制线程集实例

队列以一种先进先出的方式管理数据.如果你试图向一个已经满了的阻塞队列中添加一个元素,或是从一个空的阻塞队列中移除一个元素,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具.工作者线程可以定期的把中间结果存到阻塞队列中.而其他工作者线程把中间结果取出并在将来修改它们.队列会自动平衡负载.如果第一个线程集运行的比第二个慢,则第二个线程集在等待结果时就会阻塞.如果第一个线程集运行的快,那么它将等待第二个线程集赶上来. 下面的程序展示了如何使用阻塞队列来控制线程集.程序在一个目录及它的所有子目

java控制线程运行

1.线程的控制很常见,如文件传送到一半时,需要暂停文件传送,或终止文件传送,这实际上就是控制线程的运行. 2.线程有创建.可运行.运行中.阻塞.死亡5个状态. 创建:使用new运算符创建一个线程 可运行:使用start方法启动一个线程后,系统分配了资源 运行中状态:执行线程的run方法 阻塞:运行的线程因为某种原因停止继续运行 死亡状态:线程结束 3.传统方法的安全问题 Thread的stop(),suspend(),resume(),destroy()方法,因为不安全,可能造成死锁,已经不再使

Java 控制线程的方法

Java 的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程的执行. join 线程 Thread 提供了让一个线程等待另一个线程完成的方法-- join() 方法.当在某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到被 join() 方法加入的 join 线程执行完为止. join() 方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程.当所有的小问题都得到处理后,再调用主线程来进一步操作. public cl