Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 精确捕获回路 问题_C#_.net_Wait_Thread Sleep - Fatal编程技术网

C# 精确捕获回路 问题

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

我正在使用FPS/FPM/FPH(秒、分钟、小时)控件实现一个捕获循环。这意味着用户可以正常捕获某些内容,也可以随着时间推移捕获某些内容

这是我的密码:

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设置系统范围的计时器分辨率。 看

有关时钟分辨率的详细信息,请参阅。您可以使用系统内部的clockres检查当前系统范围的计时器分辨率

请参见示例输出:

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**