Skip to main content

A better sleep method than Thread.Sleep in C sharp

Sleep.CS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TimerNoCpuConsume
{
    class Timer
    {
        public delegate void TimerCompleteDelegate();

        [DllImport("kernel32.dll")]
        static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);

        [DllImport("kernel32.dll")]
        static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long ft, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume);

        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [DllImport("User32.dll")]
        static extern int MsgWaitForMultipleObjects(int nCount, ref IntPtr handle, bool fWaitAll, int dwMilliseconds, int dwWakeMask);


        /// <summary>
        /// No occupation of cpu, the window does not get stuck, does not affect other code execution
        /// </summary>
        /// <param name="time">mill seconds</param>
        public static bool Sleep(int time)
        {
            TimerCompleteDelegate TimerComplete = new TimerCompleteDelegate(TimerCompleted);
            long Interval = -10 * time * 1000;//占8字节
            //Create of the timer
            IntPtr handle = CreateWaitableTimer(IntPtr.Zero, true, "WaitableTimer");
            SetWaitableTimer(handle, ref Interval, 0, TimerComplete, IntPtr.Zero, true);
            //wait for message
           
            while (MsgWaitForMultipleObjects(1, ref handle, false, -1, 255) != 0)
            {
                
                Application.DoEvents();
            }
            return CloseHandle(handle);
        }
        private static void TimerCompleted()
        {
            // Once the timer expires, the routine is executed. This is performed by a program implemented independently of the class that called the OnTimeRebug event.
        }

    }
}


Calling the method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace TimerNoCpuConsume
{
    class Program
    {
        static void Main(string[] args)
        {            
            Timer.Sleep(30000);
            Console.WriteLine("Done!");
            Console.Read();
        }
    }
}

Comments