使用基于秒表的 Func 作为循环控制变量
Using a Stopwatch based Func as loop control variable
尝试使用 Func<bool>
作为循环控制变量,如下所示似乎让 Resharper 感到不安。给定以下秒表:
var executionTimeStopwatch = new Stopwatch();
executionTimeStopwatch.Start();
这会引发“循环控制变量永远不会在循环内更新”警告:
Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
while (!mustStop()) // -> function call
{
// ...
}
然而,这不是:
Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
var k = false; // -> declaration
while (!k) // -> used for loop control
{
k = mustStop(); // -> explicit update
// ...
}
我不明白这些代码的执行结果有何不同;因为 mustStop()
取决于秒表,所以每次调用它时都应该进行不同的评估。
我是不是漏掉了什么?
Am I missing something?
不,两个代码块没有不同。事实上,在大多数情况下,当使用发布模式编译时,编译器会优化第二个块以删除变量 k
。
Resharper 无法证明循环变量在循环内部发生了变化,因为它发生在另一个方法中。简单的 resharper 不够聪明,无法确定 mustStop
委托在多次调用时是否可能 return 不同的值。
在这种情况下,您可以忽略警告或取消警告。
这是 ReSharper 中的一个已知问题,RSRP 451141。
RSRP-451141 Incorrect Loop control variable is never changed inside
loop
The following code will generate an incorrect "Loop control variable
is never changed inside loop":
/// <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;
}
目前没有指示修复时间表。
RSRP 429291 看起来也很相似。
尝试使用 Func<bool>
作为循环控制变量,如下所示似乎让 Resharper 感到不安。给定以下秒表:
var executionTimeStopwatch = new Stopwatch();
executionTimeStopwatch.Start();
这会引发“循环控制变量永远不会在循环内更新”警告:
Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
while (!mustStop()) // -> function call
{
// ...
}
然而,这不是:
Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
var k = false; // -> declaration
while (!k) // -> used for loop control
{
k = mustStop(); // -> explicit update
// ...
}
我不明白这些代码的执行结果有何不同;因为 mustStop()
取决于秒表,所以每次调用它时都应该进行不同的评估。
我是不是漏掉了什么?
Am I missing something?
不,两个代码块没有不同。事实上,在大多数情况下,当使用发布模式编译时,编译器会优化第二个块以删除变量 k
。
Resharper 无法证明循环变量在循环内部发生了变化,因为它发生在另一个方法中。简单的 resharper 不够聪明,无法确定 mustStop
委托在多次调用时是否可能 return 不同的值。
在这种情况下,您可以忽略警告或取消警告。
这是 ReSharper 中的一个已知问题,RSRP 451141。
RSRP-451141 Incorrect Loop control variable is never changed inside loop
The following code will generate an incorrect "Loop control variable is never changed inside loop":
/// <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; }
目前没有指示修复时间表。
RSRP 429291 看起来也很相似。