C# 精确捕获回路 问题
我正在使用FPS/FPM/FPH(秒、分钟、小时)控件实现一个捕获循环。这意味着用户可以正常捕获某些内容,也可以随着时间推移捕获某些内容 这是我的密码:C# 精确捕获回路 问题,c#,.net,wait,thread-sleep,C#,.net,Wait,Thread Sleep,我正在使用FPS/FPM/FPH(秒、分钟、小时)控件实现一个捕获循环。这意味着用户可以正常捕获某些内容,也可以随着时间推移捕获某些内容 这是我的密码: private System.Threading.CancellationTokenSource _captureToken; private List<long> _timeList = new List<long>(); private void CaptureRun(int interval) { var
private System.Threading.CancellationTokenSource _captureToken;
private List<long> _timeList = new List<long>();
private void CaptureRun(int interval)
{
var sw = new Stopwatch();
while (_captureToken != null && !_captureToken.IsCancellationRequested)
{
sw.Restart();
//Capture happens here...
//With or without my capture code, the result is the same (the difference in average time).
//So I removed this part of the code to make it easier to understand.
//If behind wait time, wait before capturing again.
if (sw.ElapsedMilliseconds < interval)
System.Threading.SpinWait.SpinUntil(() => sw.ElapsedMilliseconds >= interval);
_timeList.Add(sw.ElapsedMilliseconds);
}
}
//Code that starts the capture (simplified).
private void StopCapture()
{
_captureToken = new System.Threading.CancellationTokenSource();
Task.Run(() => CaptureRun(16), _captureToken.Token);
}
//Code that stops the capture.
private void StopCapture()
{
if (_captureToken != null)
{
_captureToken.Cancel();
_captureToken.Dispose();
_captureToken = null;
}
}
睡眠15毫秒时会延迟15毫秒,睡眠16毫秒时会延迟30毫秒,这是因为SpinWait在引擎盖环境下使用。滴答数依赖于系统时钟,而系统时钟的分辨率显然是15毫秒。 您可以使用timeBeginPeriod设置系统范围的计时器分辨率。 看
C:>clockres
Clockres v2.1 - Clock resolution display utility
Copyright (C) 2016 Mark Russinovich
Sysinternals
Maximum timer interval: 15.625 ms
Minimum timer interval: 0.500 ms
**Current timer interval: 15.625 ms**
WPF应用程序运行时(例如Visual Studio)
因为每个WPF应用程序都会将时钟分辨率更改为1ms,所以得到1ms的分辨率。这也被一些人用作“修复”问题的变通方法。@marsze Precision也许。Windows没有精确的时间。是否有接近精确的可用时间?可能的重复:您应该在一个紧密的循环中执行代码并进行测量。不要担心延迟感兴趣,我的建议是“当前计时器间隔:0.500毫秒”。第二个链接包含对计时器分辨率全局性质的更改,您现在可能正在体验这种更改。在您自己的应用程序中调用timebeginPeriod是最安全的选择,因为您不能再依赖其他进程来调用它,也不能对您的应用程序有效。谢谢。我创建了一个扩展类并应用于我的代码。一切都很好,我能达到平均16毫秒。只有一个问题,你认为在我的情况下,
SpinWait
仍然有意义吗?@NickeManarin:不,SpinWait/锁是超级特别的。如果你等待的时间超过1毫秒,你就浪费了电能。你可以使用高精度计时器,或者在剩下的时间里尝试睡眠和旋转的组合。如果您对ms没有意见,可以执行var sw=Stopwatch.StartNew();while(sw.appeased.totalmillizesMaximum timer interval: 15.625 ms
Minimum timer interval: 0.500 ms
**Current timer interval: 1.000 ms**