ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

准确计算时间差

2019-07-07 09:37:51  阅读:231  来源: 互联网

标签:return System long 时间差 计算 Stopwatch using public 准确


原文链接:http://www.cnblogs.com/wysky/archive/2007/12/06/985779.html 简单地使用 beginDate - endDate 不精确,总是某个值的倍数,比如 0.015625 秒的倍数,值比较小时,干脆就是个0 (0 倍)。

.NET Framework v2.0 中新增了一个 System.Diagnostics.Stopwatch 对象,本文就是说用它来计算时间差,.NET 2.0 中是现成的,因此对 2.0 来说,这文章没什么意义,只要知道有这个对象就可以了,用法也相当简单,举例:
public void SomeMethod()
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    // do something 
    // 仅仅简单举例, Stopwatch 还提供了其他更为详细的属性和方法。
    Console.WriteLine("Elapsed Seconds: {0}", stopwatch.Elapsed.TotalSeconds);
}
在 1.1 里没有提供,但只需把该对象完整的反编译代码 Copy 出来自建一个 Stopwatch 对象,再做一点小改动就 OK 了。 代码与举例:
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;

namespace Zealot.Framework.Web.Utils
{
    /// <summary>
    /// v1.1 没有 Stopwatch,从 v2.0 复制出来
    /// </summary>
    public class Stopwatch
    {
        // Fields
        private long elapsed;
        public static readonly long Frequency;
        public static readonly bool IsHighResolution;
        private bool isRunning;
        private long startTimeStamp;
        private static readonly double tickFrequency;
        private const long TicksPerMillisecond = 0x2710;
        private const long TicksPerSecond = 0x989680;

        // Methods
        static Stopwatch()
        {
            if (!SafeNativeMethods.QueryPerformanceFrequency(out Frequency))
            {
                IsHighResolution = false;
                Frequency = 0x989680;
                tickFrequency = 1;
            }
            else
            {
                IsHighResolution = true;
                tickFrequency = 10000000;
                tickFrequency /= (double)Frequency;
            }
        }

        public Stopwatch()
        {
            this.Reset();
        }

        private long GetElapsedDateTimeTicks()
        {
            long rawElapsedTicks = this.GetRawElapsedTicks();
            if (IsHighResolution)
            {
                double num2 = rawElapsedTicks;
                num2 *= tickFrequency;
                return (long)num2;
            }
            return rawElapsedTicks;
        }

        private long GetRawElapsedTicks()
        {
            long elapsed = this.elapsed;
            if (this.isRunning)
            {
                long num3 = GetTimestamp() - this.startTimeStamp;
                elapsed += num3;
            }
            return elapsed;
        }

        public static long GetTimestamp()
        {
            if (IsHighResolution)
            {
                long num = 0;
                SafeNativeMethods.QueryPerformanceCounter(out num);
                return num;
            }
            return DateTime.UtcNow.Ticks;
        }

        public void Reset()
        {
            this.elapsed = 0;
            this.isRunning = false;
            this.startTimeStamp = 0;
        }

        public void Start()
        {
            if (!this.isRunning)
            {
                this.startTimeStamp = GetTimestamp();
                this.isRunning = true;
            }
        }

        public static Stopwatch StartNew()
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            return stopwatch;
        }

        public void Stop()
        {
            if (this.isRunning)
            {
                long num2 = GetTimestamp() - this.startTimeStamp;
                this.elapsed += num2;
                this.isRunning = false;
            }
        }

        // Properties
        public TimeSpan Elapsed
        {
            get
            {
                return new TimeSpan(this.GetElapsedDateTimeTicks());
            }
        }

        public long ElapsedMilliseconds
        {
            get
            {
                return (this.GetElapsedDateTimeTicks() / ((long)0x2710));
            }
        }

        public long ElapsedTicks
        {
            get
            {
                return this.GetRawElapsedTicks();
            }
        }

        public bool IsRunning
        {
            get
            {
                return this.isRunning;
            }
        }
    }
}
编译时发现有 2 处错误,无法找到 SafeNativeMethods 对象,因为它是 internal 访问限制的。 而 在这个类里用到了 SafeNativeMethods 中的两个方法,QueryPerformanceFrequency 和 QueryPerformanceCounter,把他们也反编译出来,直接加入自建的 Stopwatch 类当中,或者在与 Stopwatch 相同的命名空间下同样自建一个 SafeNativeMethods 类就可以了。
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;

namespace Zealot.Framework.Web.Utils
{
    [SuppressUnmanagedCodeSecurity]
    internal class SafeNativeMethods
    {
        [DllImport("kernel32.dll")]
        internal static extern bool QueryPerformanceCounter(out long value);

        [DllImport("kernel32.dll")]
        internal static extern bool QueryPerformanceFrequency(out long value);
    }
}
转自:http://www.zealotforce.net/reply-638.aspx

转载于:https://www.cnblogs.com/wysky/archive/2007/12/06/985779.html

标签:return,System,long,时间差,计算,Stopwatch,using,public,准确
来源: https://blog.csdn.net/weixin_30810583/article/details/94961451

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有