定时器

using System;
using System.Collections.Generic;
using System.Diagnostics; 
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ThreadState = System.Threading.ThreadState;

namespace ConsoleApp1
{
    public class FrameTimer
    {
        static FrameTimer()
        {
            timerThread = new Thread(timerRun);
            timerThread.Start();
            var GuardThread = new Thread(GuardFunc);
            GuardThread.Start();
        }


        public static void SetInterval(IRunnable handler, TimeSpan timeout, string timerName = "Default", string id = "Default")
        {
            var timerRunner = new TimerRunner
            {
                ID = id,
                TimerName = timerName,
                StartTime = DateTime.Now,
                IRunning = handler,
                TimeOutSpan = timeout
            };
            timerRunner.SetActionTime();
            try
            {
                if (string.Equals("Default", id, StringComparison.OrdinalIgnoreCase))
                {
                    addTimer(timerRunner);
                }
                else
                {
                    var timeritem = getTimer(id);
                    if (timeritem == null)
                    {
                        addTimer(timerRunner);
                    }
                    else
                    {
                        throw new Exception("当前任务已经存在");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }
        }

        static void addTimer(TimerRunner timeritem)
        {
            try
            {
                _LockSlim.AcquireWriterLock(TimeSpan.FromSeconds(5));
                timerRunners.Add(timeritem);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }
            finally
            {
                _LockSlim.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// 按ID查询任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        static TimerRunner getTimer(string id)
        {
            try
            {
                _LockSlim.AcquireReaderLock(TimeSpan.FromSeconds(5));
                var timeritem = timerRunners.FirstOrDefault(t => string.Equals(t.ID, id, StringComparison.OrdinalIgnoreCase));
                return timeritem;
            }
            catch (Exception ex)
            {

                Debug.WriteLine(ex.StackTrace);
                return null;
            }
            finally
            {
                _LockSlim.ReleaseReaderLock();
            }
        }

        static void RemoveJob(TimerRunner timeritem)
        {
            try
            {
                _LockSlim.AcquireWriterLock(TimeSpan.FromSeconds(5));
                timerRunners.Remove(timeritem);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
            }
            finally
            {
                _LockSlim.ReleaseWriterLock();
            }
        }


        /// <summary>
        /// 按ID停止任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Tuple<bool, string> StopJob(string id)
        {
            if (string.Equals("Default", id, StringComparison.OrdinalIgnoreCase))
            {

                return new Tuple<bool, string>(false, "无法停止默认任务");
            }
            var timeritem = getTimer(id);
            if (timeritem == null)
            {
                return new Tuple<bool, string>(false, "无法停止不存在任务");
            }
            else
            {
                try
                {
                    RemoveJob(timeritem);
                    var tp = new Tuple<bool, string>(true, "停止任务成功");
                    return tp;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.StackTrace);
                }


            }

            return null;
        }


        /// <summary>
        /// 任务集合
        /// </summary>
        static readonly List<TimerRunner> timerRunners = new List<TimerRunner>();
        /// <summary>
        /// 
        /// </summary>
        private static ReaderWriterLock _LockSlim = new ReaderWriterLock();
        // SetInterval(handler, timeout, starttime, endtime)

        private static Thread timerThread;
        private static void timerRun()
        {
            while (true)
            {
                try
                {
                    Thread.Sleep(TimeSpan.FromMilliseconds(500));
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.StackTrace);
                }
                try
                {
                    _LockSlim.AcquireReaderLock(TimeSpan.FromSeconds(5));
                    foreach (var timerRunner in timerRunners)
                    {
                        var now = DateTime.Now;
                        if (timerRunner.ActionTime != null)
                        {
                            var timeUntilTrigger = timerRunner.ActionTime - now;

                            if (timeUntilTrigger <= TimeSpan.Zero)
                            {
                                //执行
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        timerRunner.IRunning.Run();
                                    }
                                    catch (Exception ex)
                                    {
                                            #region 移除发生异常任务  
                                            try
                                        {
                                            RemoveJob(timerRunner);
                                        }
                                        catch (Exception exception)
                                        {
                                            Debug.WriteLine(exception.StackTrace);
                                        }

                                            #endregion

                                            Debug.WriteLine(ex.StackTrace);
                                    }
                                });
                                timerRunner.SetActionTime();
                            }
                        }
                    }
                }
                finally
                {
                    _LockSlim.ReleaseReaderLock();
                }


            }
        }
        private static void GuardFunc()
        {
            while (true)
            {
                try
                {
                    Thread.Sleep(TimeSpan.FromSeconds(10));
                    if (timerThread.ThreadState != ThreadState.Running && timerThread.ThreadState != ThreadState.WaitSleepJoin)
                    {
                        if (timerThread.ThreadState == ThreadState.Stopped
                            || timerThread.ThreadState == ThreadState.Aborted)
                        {
                            timerThread.Abort();
                            Console.WriteLine(timerThread.ThreadState);
                            timerThread = new Thread(timerRun);
                            timerThread.Start();
                        }
                    }
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    int n = 0;
                    foreach (ProcessThread th in Process.GetCurrentProcess().Threads)
                    {
                        Debug.WriteLine(th.ThreadState);
                        if (th.ThreadState == System.Diagnostics.ThreadState.Running)
                        {
                            n++;
                        }
                    }
                    Debug.WriteLine(n);




                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.StackTrace);
                }

            }
        }
    }

    public class TimerRunner
    {
        public IRunnable IRunning
        {
            get;
            set;
        }
        public string TimerName { get; set; }

        public string ID { get; set; }

        public TimeSpan TimeOutSpan { get; set; }


        public DateTime StartTime { get; set; }

        public DateTime? EndTime { get; set; }


        public DateTime? ActionTime { get; set; }


        public void SetActionTime()
        {
            var actionTime = DateTime.Now + TimeOutSpan;
            if (GetActionTimeOut(actionTime))
            {
                ActionTime = actionTime;
            }
            else
            {
                ActionTime = null;
            }
        }

        /// <summary>
        /// 判断是否超时
        /// </summary>
        /// <param name="actionTime"></param>
        /// <returns></returns>
        public bool GetActionTimeOut(DateTime actionTime)
        {
            if (EndTime != null)
            {
                if (actionTime <= EndTime)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return true;
            }
        }

    }

    public interface IRunnable
    {
        void Run();
    }

}

  

原文地址:https://www.cnblogs.com/robertyao/p/10315541.html