Alternatives to Thread.Sleep()

后端 未结 11 1221
清歌不尽
清歌不尽 2020-11-27 03:48

Every N minutes we want to run through a list of tasks. So we\'ve created a task executor with a

do { DoWork(); }while(!stopRequested)

No

相关标签:
11条回答
  • 2020-11-27 04:13

    You could use a System.Timers.Timer and perform the work in its elapse handler.

    0 讨论(0)
  • 2020-11-27 04:15

    You could use an ManualResetEvent that you set when it's time to stop, and then do a WaitOne on it.

    0 讨论(0)
  • 2020-11-27 04:15

    If all your thread is doing is something like:

    while (!stop_working)
    {
        DoWork();
        Thread.Sleep(FiveMinutes);
    }
    

    Then I would suggest not using a thread at all. First, there's no particularly good reason to incur the system overhead of a dedicated thread that spends most of its time sleeping. Secondly, if you set the stop_working flag 30 seconds after the thread stops sleeping, you'll have to wait four and a half minutes before the thread wakes up and terminates.

    I'd suggest as others have: use a timer:

    System.Threading.Timer WorkTimer;
    
    // Somewhere in your initialization:
    
    WorkTimer = new System.Threading.Timer((state) =>
        {
            DoWork();
        }, null, TimeSpan.FromMinutes(5.0), TimeSpan.FromMinutes(5.0));
    

    And to shut down:

     WorkTimer.Dispose();
    
    0 讨论(0)
  • 2020-11-27 04:15

    I've used both a Timer in a WinForms application and a console app started periodically by a ScheduledTask on a server. The WinForms with a timer has been used in cases when I want it to pop up notifications that it ran and what it found (I've set these to mimize to the systray). For situations where I only want to be notified if something goes wrong on a server, I've put them on the server as console apps and run them as Scheduled Tasks. That seems to work quite well.

    I think I tried using Sleep in the apps where I now use Timers, and didn't like the result. For one thing, using a Timer I am able to call up the minimized app very easily in order to set or change settings on the front. If the app is asleep, you have difficulty regaining access while it is slumbering.

    0 讨论(0)
  • 2020-11-27 04:27

    As other answerers have said, Timers may work well for you.

    If you do want your own thread, I wouldn't use Thread.Sleep here, if only because if you need to shut down the application, there's no good way to tell it to exit the sleep. I've used something like this before.

    class IntervalWorker
    {
        Thread workerThread;
        ManualResetEventSlim exitHandle = new ManualResetEventSlim();
    
        public IntervalWorker()
        {
            this.workerThread = new Thread(this.WorkerThread);
            this.workerThread.Priority = ThreadPriority.Lowest;
            this.workerThread.IsBackground = true;
        }
    
        public void Start()
        {
            this.workerThread.Start();
        }
    
        public void Stop()
        {
            this.exitHandle.Set();
            this.workerThread.Join();
        }
    
        private void WorkerThread()
        {
            int waitTimeMillis = 10000; // first work 10 seconds after startup.
    
            while (!exitHandle.Wait(waitTimeMillis))
            {
                DoWork();
    
                waitTimeMillis = 300000; // subsequent work at five minute intervals.
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 04:28

    The three options that I can think of off the top of my head are :

    • System.Threading.Timer (More...)
    • Monitor.Wait (More...)
    • System.Timers.Timer (More...)

    but I am sure as many will mention - Thread.Sleep() isn't all that bad.

    0 讨论(0)
提交回复
热议问题