我记录网站综合系统 -- 技术原理解析[番外篇:自己做Stopwatch]

刚才无聊,又看了看我记录的代码,无意中又看到了那个Stopwatch的代码。

现在大家都知道可以使用系统的Stopwatch计算时间。不过我们的鸡蛋同志,居然想自己实现Stopwatch。

这篇不属于wojilu的一个正式的原理解析,拿出来给大家讨论一下。

代码位置:wojilu\_wojilu\Stopwatch.cs

 

 1 /*
 2  * Copyright 2010 www.wojilu.com
 3  * 
 4  * Licensed under the Apache License, Version 2.0 (the "License");
 5  * you may not use this file except in compliance with the License.
 6  * You may obtain a copy of the License at
 7  * 
 8  *      http://www.apache.org/licenses/LICENSE-2.0
 9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 using System;
18 using System.ComponentModel;
19 using System.Runtime.InteropServices;
20 
21 namespace wojilu {
22 
23     /// <summary>
24     /// 秒表,用于测试程序耗时
25     /// </summary>
26     public class Stopwatch {
27 
28         private Boolean _IsStop;
29         private long frequency;
30         private decimal multiplier = 1000000000M;
31         private long start;
32         private long stop;
33 
34         [DllImport( "KERNEL32" )]
35         private static extern Boolean QueryPerformanceCounter( out long lpPerformanceCount );
36 
37         [DllImport( "Kernel32.dll" )]
38         private static extern Boolean QueryPerformanceFrequency( out long lpFrequency );
39 
40         public Stopwatch() {
41             if (!QueryPerformanceFrequency( out this.frequency )) {
42                 throw new Win32Exception();
43             }
44         }
45 
46         /// <summary>
47         /// 开始启动
48         /// </summary>
49         public void Start() {
50             this._IsStop = false;
51             QueryPerformanceCounter( out this.start );
52         }
53 
54         /// <summary>
55         /// 停止
56         /// </summary>
57         public void Stop() {
58             if (!this._IsStop) {
59                 QueryPerformanceCounter( out this.stop );
60                 this._IsStop = true;
61             }
62         }
63 
64         /// <summary>
65         /// 总共耗时(毫秒)
66         /// </summary>
67         public double ElapsedMilliseconds {
68             get {
69                 double result = this.getDuration() / 1000000.0;
70                 if (result < 0) result = 0;
71                 return result;
72             }
73         }
74 
75         /// <summary>
76         /// 总共耗时(秒)
77         /// </summary>
78         public double ElapsedSeconds {
79             get {
80                 double result = this.ElapsedMilliseconds / 1000.0;
81                 if (result < 0) result = 0;
82                 return result;
83             }
84         }
85 
86         private double getDuration() {
87             return (((this.stop - this.start) * ((double)this.multiplier)) / ((double)this.frequency));
88         }
89 
90     }
91 }

Google大神给了我们这段代码的一些参考:

精确的时间计时,有时候是非常必要的。比如播放多媒体时视频与音频的时间同步,还有在测试代码的性能时,也需要使用到非常精确的时间计时。还有测试硬件的性能时,也需要精确的时间计时。这时就需要使用QueryPerformanceCounter来查询定时器的计数值,如果硬件里有定时器,它就会启动这个定时器,并且不断获取定时器的值,这样的定时器精度,就跟硬件时钟的晶振一样精确的。

  函数QueryPerformanceCounter和QueryPerformanceFrequency声明如下:

WINBASEAPI
BOOL
WINAPI
QueryPerformanceCounter(
    __out LARGE_INTEGER 
*lpPerformanceCount
    );
 
WINBASEAPI
BOOL
WINAPI
QueryPerformanceFrequency(
    __out LARGE_INTEGER 
*lpFrequency
    );

 

这个例子,大概能学到的东西,可能就是如何使用系统API在C#里面了。。。。呵呵

小品文,编辑大神,就让他留在首页吧。。。。鸡蛋同志写这段代码估计花了1个小时了。。。。。

 

我记录网址 http://www.wojilu.com/

欢迎大家加入我记录开发团队

 

 

posted @ 2011-06-13 21:19  灰毛毛  阅读(1367)  评论(0编辑  收藏  举报