C#【时间相关篇】实现微秒(Microseconds)级延时

方法一:System.Diagnostics.Stopwatch【相对方法二精度更高,也更稳定些】

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 20; i++)
            {
                double result = delayUs(0.005);//延时0.005ms,即5us
                Console.WriteLine(result);
            }
          
            Console.ReadLine();
        }

        /// <summary>
        ///  微秒延时
        /// </summary>
        /// <param name="time">延时时间,单位:ms</param>
        /// <returns></returns>
        public static double delayUs(double time)
        {
            System.Diagnostics.Stopwatch stopTime = new System.Diagnostics.Stopwatch();

            stopTime.Start();
            while (stopTime.Elapsed.TotalMilliseconds < time) { }
            stopTime.Stop();

            return stopTime.Elapsed.TotalMilliseconds;
        }

    }
}

运行结果:【我又测试了1000次,后边基本可以稳定在0.005(还是比较稳的)】
在这里插入图片描述

方法二:调用WIN API中的QueryPerformanceCounter

1、延时5us时,精度很差

using System;
using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch stopTime = new System.Diagnostics.Stopwatch();
            stopTime.Start();
            for (int i = 0; i < 20; i++)
            {
                delayUs(5);//延时即5us,0.005ms
                Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            }
            Console.WriteLine("测试结束");
            Console.ReadLine();
        }

      
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceCounter(ref long x);
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceFrequency(ref long x);


        /// <summary>
        /// 微秒延时
        /// </summary>
        /// <param name="delay_Time">延时时间,单位:us</param>
        public static void delayUs(long delay_Time)
        {
            long stop_Value = 0;
            long start_Value = 0;
            long freq = 0;
            long n = 0;

            QueryPerformanceFrequency(ref freq);  //获取CPU频率
            long count = delay_Time * freq / 1000000;   //这里写成1000000就是微秒,写成1000就是毫秒
            QueryPerformanceCounter(ref start_Value); //获取初始前值

            while (n < count) //不能精确判定
            {
                QueryPerformanceCounter(ref stop_Value);//获取终止变量值
                n = stop_Value - start_Value;
            }
        }

    }
}

运行结果【延时5us时】:
在这里插入图片描述
在这里插入图片描述

2、延时500us时,精度高些

在这里插入图片描述
在这里插入图片描述

500us延时下,进一步研究:

500us延时下,分别延时1s、2s、4s、5s、10s、20s、40s、60s、120s、240s。测试源码如下:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopTime = new Stopwatch();
            stopTime.Start();

            //【01】总用时1s
            for (int i = 0; i < 2000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【02】总用时2s
            stopTime = new Stopwatch();
            stopTime.Start();          
            for (int i = 0; i < 4000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【03】总用时3s
            stopTime = new Stopwatch();
            stopTime.Start();           
            for (int i = 0; i < 6000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【04】总用时4s
            stopTime = new Stopwatch();
            stopTime.Start();           
            for (int i = 0; i < 8000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【05】总用时5s
            stopTime = new Stopwatch();
            stopTime.Start();           
            for (int i = 0; i < 10000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【06】总用时10s
            stopTime = new Stopwatch();
            stopTime.Start();         
            for (int i = 0; i < 20000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【07】总用时20s
            stopTime = new Stopwatch();
            stopTime.Start();         
            for (int i = 0; i < 40000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【08】总用时40s
            stopTime = new Stopwatch();
            stopTime.Start();       
            for (int i = 0; i < 80000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【09】总用时60s
            stopTime = new Stopwatch();
            stopTime.Start();      
            for (int i = 0; i < 120000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();

            //【10】总用时120s
            stopTime = new Stopwatch();
            stopTime.Start();       
            for (int i = 0; i < 240000; i++)
            {
                delayUs(500);//延时即5us,0.005ms
            }
            Console.WriteLine(stopTime.Elapsed.TotalMilliseconds);
            stopTime.Stop();


            Console.WriteLine("测试结束");
            Console.ReadLine();
        }


        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceCounter(ref long x);
        [DllImport("kernel32.dll")]
        extern static short QueryPerformanceFrequency(ref long x);


        /// <summary>
        /// 微秒延时
        /// </summary>
        /// <param name="delay_Time">延时时间,单位:us</param>
        public static void delayUs(long delay_Time)
        {
            long stop_Value = 0;
            long start_Value = 0;
            long freq = 0;
            long n = 0;

            QueryPerformanceFrequency(ref freq);  //获取CPU频率
            long count = delay_Time * freq / 1000000;   //这里写成1000000就是微秒,写成1000就是毫秒
            QueryPerformanceCounter(ref start_Value); //获取初始前值

            while (n < count) //不能精确判定
            {
                QueryPerformanceCounter(ref stop_Value);//获取终止变量值
                n = stop_Value - start_Value;
            }
        }
    }
}

多次运行结果如下:
在这里插入图片描述
对于测试结果1进行分析:

  • 跑1min相差50000us,共120000个循环,每个循环(500us)相差0.417us(50000÷120000=0.417)

  • 跑2min相差111000us,共240000个循环,每个循环(500us)相差0.4625us(111000÷240000=0.4625)

结论:【500us的延时,相对来说还是很准的】

方法三:DateTime.Ticks【延时效果最差】

DateTime.Ticks:表示0001 年 1 月 1 日午夜 12:00:00 以来所经历的 100 纳秒数,即Ticks的属性为100纳秒(1Ticks = 0.0001毫秒)。

//延时,单位:微妙us
 public static void delay(long t)
        {
            long b = DateTime.Now.Ticks / 10;
            long e = 0; long c = 0; ;
            do
            {
                e = DateTime.Now.Ticks / 10;
                c = e - b;               
            }
            while (c < t);
        }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElecNoon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值