C# 我应该使用Timer、ThreadPool、AutoResteEvent还是“加入”模拟?

C# 我应该使用Timer、ThreadPool、AutoResteEvent还是“加入”模拟?,c#,timer,impersonation,sleep,threadpool,C#,Timer,Impersonation,Sleep,Threadpool,读了这么多书后,我明白了这一点:睡眠是一种精神。相反,一般的共识是服务器端任务应该使用计时器、线程池,或者可能使用连接 有人提到了处理计时器的困难 另一个提到使用waitOne 问题: 启动一个长时间运行的任务时,每30秒、1分钟或5分钟重复一次,正确的方法是什么?约束条件是,如果该任务的上一次运行时间超过了间隔32秒或7分钟,那么我希望可以选择终止前一个实例,或者不执行新实例 一个潜在的问题是,我打算在这些线程上使用p/Invoke或根据需要使用模拟 我不知道该采取什么方法,为什么 可能的答案

读了这么多书后,我明白了这一点:睡眠是一种精神。相反,一般的共识是服务器端任务应该使用计时器、线程池,或者可能使用连接

有人提到了处理计时器的困难

另一个提到使用waitOne

问题:

启动一个长时间运行的任务时,每30秒、1分钟或5分钟重复一次,正确的方法是什么?约束条件是,如果该任务的上一次运行时间超过了间隔32秒或7分钟,那么我希望可以选择终止前一个实例,或者不执行新实例

一个潜在的问题是,我打算在这些线程上使用p/Invoke或根据需要使用模拟

我不知道该采取什么方法,为什么

可能的答案1

这个例子看起来很简单,代码混乱程度最低

    // initially set to a "non-signaled" state, ie will block
    // if inspected
   private readonly AutoResetEvent _isStopping = new AutoResetEvent(false);
    /// <summary>
    /// from...
    /// https://stackoverflow.com/questions/2822441/system-timers-timer-threading-timer-vs-thread-with-whileloop-thread-sleep-for-p/2822506#2822506
    /// </summary>
    public void SampleDelay1()
    {
        TimeSpan waitInterval = TimeSpan.FromMilliseconds(1000);

        // will block for 'waitInterval', unless another thread,
        // say a thread requesting termination, wakes you up. if
        // no one signals you, WaitOne returns false, otherwise
        // if someone signals WaitOne returns true
        for (; !_isStopping.WaitOne(waitInterval); )
        {
            // do your thang!
        }
    }
可能的答案2

本例提供了类似的功能,但使用的匿名类型可能是公司不允许的,因为这些公司在其编码标准中不允许使用匿名类型

 /// <summary>
    /// Disposable Timer instance from 
    /// https://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for-delayed-execution
    /// </summary>
    class TimerStackOverFlow
    {
   // Created by Roy Feintuch 2009
        // Basically we wrap a timer object in order to send itself as a context in order
        // to dispose it after the cb invocation finished. This solves the problem of timer 
        // being GCed because going out of context
        public static void DoOneTime(ThreadStart cb, TimeSpan dueTime)
        {
            var td = new TimerDisposer();
            // Is the next object System.Timers, or System.Threading
            var timer = new Timer(myTdToKill =>
            {
                try
                {
                    cb();
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(string.Format("[DoOneTime] Error occured while invoking delegate. {0}", ex), "[OneTimer]");
                }
                finally
                {
                    ((TimerDisposer)myTdToKill).InternalTimer.Dispose();
                }
            },
                        td, dueTime, TimeSpan.FromMilliseconds(-1));

            td.InternalTimer = timer;
        }
    }

    class TimerDisposer
    {
        public Timer InternalTimer { get; set; }
    }

我已经多次使用您的第一种方法,而且效果很好


第二种解决方案似乎是一次性事件的基于时间的触发器的通用封装。如果您关注的是重复发生的事件,那么这种方法对我来说似乎不必要地复杂,没有从增加的复杂性中获得明显的好处。

我已经多次使用您的第一种方法,而且效果很好


第二种解决方案似乎是一次性事件的基于时间的触发器的通用封装。如果您正在查看重复发生的事件,那么这种方法对我来说似乎是不必要的复杂,没有从增加的复杂性中获得明显的好处。

谢谢,我刚刚用一个潜在的问题更新了这个问题。。。模拟。谢谢,我刚刚用一个潜在的问题更新了这个问题。。。模仿。