我在Mono上寻找一个高分辨率的滴答计数器,最好是和Win32 / .NET上的QueryPerformanceCounter大致相同的分辨率。
这是否需要在我需要支持的每个平台上作为本地调用(如QueryPerformanceCounter在.NET / Win32上)来实现? (Linux,OSX)。
我需要大约1ms的分辨率。
如果SetForegroundWindow和ShowWindowAsync不起作用,如何设置前景窗口?
构buildWindows服务的安装项目时出现问题?
如何使用C#从Windows服务访问Linux目录/文件
我如何计算WPF中的非客户端窗口大小?
有没有办法检测到“几乎”远程桌面断开连接(即短暂的高延迟时间)?
gdi +在Graphics对象上绘制图像时出现的一般错误
获取有关Windows服务的内部状态的信息
windows微秒计算精度
XP和Windows 7/8上的DateTime.Parse不同
您应该使用System.Diagnostics.Stopwatch为此。
看到我的答案在这里: https : //stackoverflow.com/a/37882723/5073786
using Mono.Unix.Native; namespace drone.StackOverflow{ internal class LinuxHiResTimer { internal event EventHandler Tick; // Tick event private System.Diagnostics.Stopwatch watch; // High resolution time const uint safeDelay = 0; // millisecond (for slightly early wakeup) private Timespec pendingNanosleepParams = new Timespec(); private Timespec threadNanosleepParams = new Timespec(); object lockObject = new object(); internal long Interval { get{ double totalNanoseconds; lock (lockObject) { totalNanoseconds= (1e9 * pendingNanosleepParams.tv_sec) + pendingNanosleepParams.tv_nsec; } return (int)(totalNanoseconds * 1e-6);//return value in ms } set{ lock (lockObject) { pendingNanosleepParams.tv_sec = value / 1000; pendingNanosleepParams.tv_nsec = (long)((value % 1000) * 1e6);//set value in ns } } } private bool enabled; internal bool Enabled { get { return enabled; } set { if (value) { watch.Start(); enabled = value; Task.Run(()=>tickGenerator()); // fire up new thread } else { lock (lockObject) { enabled = value; } } } } private Task tickGenerator() { bool bNotPendingStop; lock (lockObject) { bNotPendingStop = enabled; } while (bNotPendingStop) { // Check if thread has been told to halt lock (lockObject) { bNotPendingStop = enabled; } long curTime = watch.ElapsedMilliseconds; if (curTime >= Interval) { watch.Restart (); if (Tick != null) Tick (this,new EventArgs ()); } else { long iTimeLeft = (Interval - curTime); // How long to delay for if (iTimeLeft >= safeDelay) { // Task.Delay has resolution 15ms//await Task.Delay(TimeSpan.FromMilliseconds(iTimeLeft - safeDelay)); threadNanosleepParams.tv_nsec = (int)((iTimeLeft - safeDelay) * 1e6); threadNanosleepParams.tv_sec = 0; Syscall.nanosleep (ref threadNanosleepParams,ref threadNanosleepParams); } } } watch.Stop(); return null; } }
用法:
private myMainFunction(){ LinuxHiResTimer timReallyFast = new LinuxHiResTimer(); timReallyFast.Interval=25; // timReallyFast.Tick += new EventHandler(timReallyFast_Tick); timReallyFast.Enabled = true; } private void timReallyFast_Tick(System.Object sender,System.EventArgs e) { // Do this quickly ie PollSerialPort(); }
这里是我的答案高分辨率计时器
https://gist.github.com/drateots/436019368d32007284f8a12f1ba0f545
它可以在所有平台上运行(所以不需要using Mono.Unix.Native; ),并且在任何地方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 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
https://gist.github.com/drateots/5f454968ae84122b526651ad2d6ef2a3
在Windows 10上将计时器设置为0.5毫秒的结果:
还值得一提的是:
我在Ubuntu上对单声道有相同的精度。
在玩基准测试的时候,我看到的最大值和一个非常罕见的偏差大约是0.5毫秒(这可能意味着什么,它不是实时系统,但仍值得一提)
秒表滴答不是TimeSpan滴答。 在Windows 10机器HighResolutionTimer.TickLength是0.23 [ns]。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。