C threads perform timeout handling and concurrent thread count control instances

  • 2020-11-26 18:58:24
  • OfStack

This article illustrates the methods of C# thread execution timeout handling and concurrent thread count control. Share to everybody for everybody reference. Specific implementation methods are as follows:

Special Note:

1. For testing purposes, the execution of the stored procedure is simulated

2. The maximum number of concurrent stored procedures is limited here, but the number of concurrent threads is not controlled. It is slightly different from the title of the article, but the number of concurrent threads can be controlled by making some changes in the program

The code is as follows:


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 service
    /// </summary>
    partial class FQDService : ServiceBase
    {
        #region variable
        /// <summary>
        /// Stored procedure configuration documents
        /// </summary>
        public static XmlDocument doc;
        /// <summary>
        /// Execute the stored procedure thread count lock
        /// </summary>
        public static Object lockTreadCount = new Object();
        /// <summary>
        /// Execute the stored procedure timeout period
        /// </summary>
        public static int timeout = 1000;
        /// <summary>
        /// Wait the interval for the stored procedure to execute
        /// </summary>
        public static int interval = 100;
        /// <summary>
        /// Maximum number of stored procedures executed
        /// </summary>
        public static int maxRunProcCount = 5;
        /// <summary>
        /// Number of stored procedures executed
        /// </summary>
        public static int runProcCount = 0;
        #endregion         #region The constructor
        public FQDService()
        {
            InitializeComponent();
        }
        #endregion         #region Start the
        protected override void OnStart(string[] args)
        {
            // TODO: Add the code here to start the service.
            doc = XMLHelper.GetXmlDocument();
            System.Timers.Timer timer = new System.Timers.Timer(60 * 1000);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(RunProc);
            timer.Start();
        }
        #endregion         #region The end of the
        protected override void OnStop()
        {
            // TODO: Add code here to perform the shutdown required to stop the service.
        }
        #endregion         #region Execute stored procedure
        /// <summary>
        /// Execute stored procedure
        /// </summary>
        public void RunProc(object sender, ElapsedEventArgs e)
        {
            try
            {
                Random rnd = new Random();
                XmlNode rootNode = doc.SelectSingleNode("settings");                 foreach (XmlNode procNode in rootNode.ChildNodes) // traverse 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; // Has the stored procedure been executed
                        Thread thread = null;
                        thread = new Thread(new ParameterizedThreadStart(delegate(object obj)
                        {
                            #region Wait for the stored procedure to execute
                            lock (lockTreadCount)
                            {
                                while (runProcCount >= maxRunProcCount)
                                {
                                    Thread.Sleep(interval);
                                }
                                runProcCount++;
                            }
                            #endregion                             #region Perform stored procedure timeout handling
                            Thread threadTimer = new Thread(new ParameterizedThreadStart(delegate(object obj2)
                            {
                                Thread.Sleep(timeout);
                                if (finish == false)
                                {
                                    FileLogger.WriteLog(string.Format(" The stored procedure {0} timeouts ", procName));
                                    if (thread != null)
                                    {
                                        try
                                        {
                                            thread.Abort();
                                        }
                                        catch (Exception ex)
                                        {
                                            FileLogger.WriteErrorLog(string.Format(" The stored procedure {0} Thread termination error: {1}", procName, ex.Message));
                                        }
                                    }
                                }
                            }));
                            threadTimer.Start();
                            #endregion                             #region Prepare parameters for executing the stored procedure
                            XmlNodeList paramList = procNode.SelectSingleNode("Params").ChildNodes;
                            OracleParameter[] oracleParams = new OracleParameter[paramList.Count];
                            for (int i = 0; i < paramList.Count; i++) // traverse 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 Execute stored procedure
                                    FileLogger.WriteLog(string.Format(" Start executing the stored procedure {0}", procName));                                     // Execute stored procedure
                                    //OracleHelper.RunProcedure(procName, oracleParams);                                     // Simulate the execution of stored procedures
                                    Thread.Sleep(rnd.Next(100, 1900));                                     FileLogger.WriteLog(string.Format(" The stored procedure {0} Execute successfully ", procName));
                                    finish = true;
                                    #endregion
                                }
                                catch (Exception ex)
                                {
                                    #region Execute the stored procedure failure log
                                    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(" The stored procedure execution failed {0}({1}) : {2}", procName, strParams, ex.Message));
                                    #endregion
                                }
                            }
                            catch
                            {
                                // Catch thread termination exceptions
                            }
                            finally
                            {
                                runProcCount--;
                            }
                        }));
                        thread.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                FileLogger.WriteErrorLog(ex.Message);
            }
        }
        #endregion     }
}

Hopefully this article has helped you with your C# programming.


Related articles: