C# 使用基于秒表的Func作为循环控制变量

C# 使用基于秒表的Func作为循环控制变量,c#,while-loop,func,stopwatch,C#,While Loop,Func,Stopwatch,尝试使用Func作为循环控制变量,如下所示似乎会打乱Resharper。考虑到以下秒表: var executionTimeStopwatch = new Stopwatch(); executionTimeStopwatch.Start(); 这会引发“循环控制变量永远不会在循环内更新”警告: Func mustStop=()=>executionTimeStopwatch.elapsedmillesons函数调用 { // ... } 但是,这并不是: Func<bool>

尝试使用
Func
作为循环控制变量,如下所示似乎会打乱Resharper。考虑到以下秒表:

var executionTimeStopwatch = new Stopwatch();
executionTimeStopwatch.Start();
这会引发“循环控制变量永远不会在循环内更新”警告:

Func mustStop=()=>executionTimeStopwatch.elapsedmillesons函数调用
{
// ...
}
但是,这并不是:

Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
var k = false;      // -> declaration
while (!k)          // -> used for loop control
{
    k = mustStop(); // -> explicit update
    // ...
}
Func mustStop=()=>executionTimeStopwatch.elapsedmillesons宣言
而(!k)/->用于循环控制
{
k=mustStop();//->显式更新
// ...
}
我不明白执行这些代码的结果会有什么不同;由于
mustStop()
取决于秒表,因此每次调用秒表时,它的计算结果应该不同

我错过什么了吗

我错过什么了吗

不,两个代码块没有区别。事实上,在大多数情况下,当使用release模式编译时,编译器将优化第二个块以删除变量
k

Resharper无法证明循环变量在循环内部发生了更改,因为它发生在另一个方法中。简单地说,resharper不够聪明,无法发现
mustStop
委托在多次调用时是否会返回不同的值


在这种情况下,您可以忽略或抑制警告。

这是ReSharper中的一个已知问题

RSRP-451141内部从未更改不正确的回路控制变量 环路

以下代码将生成不正确的“回路控制变量” 在循环内从未更改“:

//
///函数将在与调用线程相同的线程上求值
/// 
/// 
///每次功能检查之间的等待时间,单位为毫秒
/// 
/// 
///如果函数最终返回true,则返回true,否则返回false
公共静态bool waitforrueonsamethread(Func函数,int-msInterval,int-msTimeout,Action-timeoutAction=null)
{
var sw=Stopwatch.StartNew();
而(!function()){
如果(sw.ElapsedMilliseconds>msTimeout){
timeoutAction?.Invoke();
返回false;
}
等待(msInterval);
}
返回true;
}
目前,没有明确的固定时间表


看起来也很相似

这只是一个警告!我认为,
Resharper
不知道您的条件是变量还是函数。只是看到变量在循环内没有变化,所以有无限循环的可能性。同样在你的情况下,
k
在循环中更新。我同意!代码验证工具毕竟不是无所不知的坦白地说,从Resharper那里得到错误警报并不罕见。幸运的是,Resharper支持在这种情况下禁用特殊警告。谢谢!对所有人,请检查以下答案(AakashM's):
Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
var k = false;      // -> declaration
while (!k)          // -> used for loop control
{
    k = mustStop(); // -> explicit update
    // ...
}
    /// <summary>
    /// Function will be evaluated on the same thread as the calling thread
    /// </summary>
    /// <param name="function"></param>
    /// <param name="msInterval">Time to wait between each check of function, in ms</param>
    /// <param name="msTimeout"></param>
    /// <param name="timeoutAction"></param>
    /// <returns>true if function eventually returned true, false otherwise</returns>
    public static bool WaitForTrueOnSameThread(Func<bool> function, int msInterval, int msTimeout, Action timeoutAction = null)
    {
        var sw = Stopwatch.StartNew();
        while (!function()) {
            if (sw.ElapsedMilliseconds > msTimeout) {
                timeoutAction?.Invoke();
                return false;
            }
            Wait(msInterval);
        }
        return true;
    }