我想要一个5毫秒精度的计时器。但目前.Net中的定时器的分辨率约为50ms。我找不到任何可以创建高精度计时器的有效解决方案,尽管有些人声称你可以在C#中实现。
发布于 2011-08-22 08:06:35
我在下面的博客中找到了这个问题的解决方案:http://web.archive.org/web/20110910100053/http://www.indigo79.net/archives/27#comment-255
它告诉你如何使用多媒体定时器来获得高频率的定时器。它对我来说工作得很好!
发布于 2011-08-21 16:04:07
对于OP专门询问的有关定期触发事件的 Timer 类的信息,可以使用。我已经修改了这个答案,在水平线下面使用了我的旧答案。
我用Timer类测试了下面的代码,似乎在我的机器上它至少可以达到14 - 15毫秒的范围。自己试一试,看看能否重现这一点。因此,低于50毫秒的响应时间是可能的,但它不能精确到1毫秒。
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();
}
}注:以下是我以前的回答,当时我认为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);如果您担心它的实际来源,文档似乎暗示它实际上在内部调用较低级别的Win32函数:
秒表类帮助操作托管代码中与计时相关的性能计数器。具体地说,可以使用频率字段和GetTimestamp方法代替非托管Win32 APIs和QueryPerformanceCounter。
发布于 2011-08-21 16:03:46
那this one呢?
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);
}
}https://stackoverflow.com/questions/7137121
复制相似问题