Mik*_*ley 15
关于OP特别询问有关Timer定期发生事件的班级的信息.我修改了这个答案,我的回答低于横向规则.
我使用Timer类测试了以下代码,看起来它至少可以在我的机器上的14-15毫秒范围内.亲自尝试一下,看看你是否可以重现这一点.因此,可能有不到50毫秒的响应时间,但它不能精确到一毫秒.
using System;
using System.Timers;
using System.Diagnostics;
public static class Test
{
public static void Main(String[] args)
{
Timer timer = new Timer();
timer.Interval = 1;
timer.Enabled = true;
Stopwatch sw = Stopwatch.StartNew();
long start = 0;
long end = sw.ElapsedMilliseconds;
timer.Elapsed += (o, e) =>
{
start = end;
end = sw.ElapsedMilliseconds;
Console.WriteLine("{0} milliseconds passed", end - start);
};
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
注意:以下是我的老答案,当时我认为OP正在谈论计时.以下仅仅是关于事物持续时间的定时的有用信息,但是没有提供以规则间隔触发事件的任何方式.为此目的,该Timer课程是必要的.
尝试使用秒表类System.Diagnostics:http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
您可以查询它以通过它的IsHighResolution字段检查它是否是高分辨率.此外,您可以检查秒表的确切分辨率:
int resolution = 1E9 / Stopwatch.Frequency;
Console.WriteLine("The minimum measurable time on this system is: {0} nanoseconds", resolution);
Run Code Online (Sandbox Code Playgroud)
如果您担心实际来源的位置,那么文档似乎暗示它实际上在内部调用较低级别的Win32函数:
秒表类可以帮助管理托管代码中与时序相关的性能计数器.具体来说,可以使用Frequency字段和GetTimestamp方法代替非托管Win32 API QueryPerformanceFrequency和QueryPerformanceCounter.
gen*_*sis 11
这一个怎么样?
public class HiResTimer
{
private bool isPerfCounterSupported = false;
private Int64 frequency = 0;
// Windows CE native library with QueryPerformanceCounter().
private const string lib = "coredll.dll";
[DllImport(lib)]
private static extern int QueryPerformanceCounter(ref Int64 count);
[DllImport(lib)]
private static extern int QueryPerformanceFrequency(ref Int64 frequency);
public HiResTimer()
{
// Query the high-resolution timer only if it is supported.
// A returned frequency of 1000 typically indicates that it is not
// supported and is emulated by the OS using the same value that is
// returned by Environment.TickCount.
// A return value of 0 indicates that the performance counter is
// not supported.
int returnVal = QueryPerformanceFrequency(ref frequency);
if (returnVal != 0 && frequency != 1000)
{
// The performance counter is supported.
isPerfCounterSupported = true;
}
else
{
// The performance counter is not supported. Use
// Environment.TickCount instead.
frequency = 1000;
}
}
public Int64 Frequency
{
get
{
return frequency;
}
}
public Int64 Value
{
get
{
Int64 tickCount = 0;
if (isPerfCounterSupported)
{
// Get the value here if the counter is supported.
QueryPerformanceCounter(ref tickCount);
return tickCount;
}
else
{
// Otherwise, use Environment.TickCount.
return (Int64)Environment.TickCount;
}
}
}
static void Main()
{
HiResTimer timer = new HiResTimer();
// This example shows how to use the high-resolution counter to
// time an operation.
// Get counter value before the operation starts.
Int64 counterAtStart = timer.Value;
// Perform an operation that takes a measureable amount of time.
for (int count = 0; count < 10000; count++)
{
count++;
count--;
}
// Get counter value when the operation ends.
Int64 counterAtEnd = timer.Value;
// Get time elapsed in tenths of a millisecond.
Int64 timeElapsedInTicks = counterAtEnd - counterAtStart;
Int64 timeElapseInTenthsOfMilliseconds =
(timeElapsedInTicks * 10000) / timer.Frequency;
MessageBox.Show("Time Spent in operation (tenths of ms) "
+ timeElapseInTenthsOfMilliseconds +
"\nCounter Value At Start: " + counterAtStart +
"\nCounter Value At End : " + counterAtEnd +
"\nCounter Frequency : " + timer.Frequency);
}
}
Run Code Online (Sandbox Code Playgroud)
我在以下博客中找到了解决此问题的方法:http://web.archive.org/web/20110910100053/http: //www.indigo79.net/archives/27#comment-255
它告诉您如何使用多媒体计时器来设置高频定时器.它对我来说工作得很好!!!
这是基于秒表计时器的实现
https://gist.github.com/DraTeots/436019368d32007284f8a12f1ba0f545
它适用于所有平台,并且在任何地方都具有高精度 StopWatch.IsHighPrecision == true
它的Elapsed事件保证不重叠(这可能很重要,因为事件处理程序内的状态更改可能不受多线程访问的保护)
以下是如何使用它:
Console.WriteLine($"IsHighResolution = {HighResolutionTimer.IsHighResolution}");
Console.WriteLine($"Tick time length = {HighResolutionTimer.TickLength} [ms]");
var timer = new HighResolutionTimer(0.5f);
// UseHighPriorityThread = true, sets the execution thread
// to ThreadPriority.Highest. It doesn't provide any precision gain
// in most of the cases and may do things worse for other threads.
// It is suggested to do some studies before leaving it true
timer.UseHighPriorityThread = false;
timer.Elapsed += (s, e) => { /*... e.Delay*/ }; // The call back with real delay info
timer.Start();
timer.Stop(); // by default Stop waits for thread.Join()
// which, if called not from Elapsed subscribers,
// would mean that all Elapsed subscribers
// are finished when the Stop function exits
timer.Stop(joinThread:false) // Use if you don't care and don't want to wait
Run Code Online (Sandbox Code Playgroud)
这是一个基准(和一个活生生的例子):https :
//gist.github.com/DraTeots/5f454968ae84122b526651ad2d6ef2a3
在 Windows 10 上将计时器设置为 0.5 毫秒的结果:

还值得一提的是:
我在 Ubuntu 上对单声道有同样的精度。
在玩基准测试时,我看到的最大和非常罕见的偏差约为 0.5 毫秒(这可能没有任何意义,它不是实时系统,但仍然值得一提)
秒表刻度不是 TimeSpan 刻度。在该 Windows 10 机器上 HighResolutionTimer.TickLength 为 0.23[ns]。
基准测试的CPU 使用率为 0.5ms 间隔为 10%,200ms 间隔为 0.1%