Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a Stopwatch based Func as loop control variable

Trying to use a Func<bool> as a loop control variable as follows seems to upset Resharper. Given the following Stopwatch:

var executionTimeStopwatch = new Stopwatch();
executionTimeStopwatch.Start();

This raises a "Loop control variable is never updated inside loop" warning:

Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
while (!mustStop()) // -> function call
{
    // ...
}

However, this doesn't:

Func<bool> mustStop = () => executionTimeStopwatch.ElapsedMilliseconds < TIMEOUT_MILLISECONDS;
var k = false;      // -> declaration
while (!k)          // -> used for loop control
{
    k = mustStop(); // -> explicit update
    // ...
}

I don't understand how the result of the execution of these codes could be different; as mustStop() depends on the Stopwatch it should evaluate differently each time it is called.

Am I missing something?

like image 986
evilmandarine Avatar asked Dec 31 '25 02:12

evilmandarine


2 Answers

Am I missing something?

No, Both code blocks are not different. In fact compiler will optimize the second block to remove the variable k in most cases when compiled with release mode.

Resharper could not prove that loop variable is changed inside the loop since it happens in another method. Simply resharper isn't clever enough to find whether the mustStop delegate may return a different value when called multiple times.

You could just ignore the warning or suppress it in this case.

like image 196
Sriram Sakthivel Avatar answered Jan 02 '26 15:01

Sriram Sakthivel


This is a known issue within 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;
    }

At present there is no indicated fix timescale.

RSRP 429291 looks pretty similar, too.

like image 31
AakashM Avatar answered Jan 02 '26 15:01

AakashM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!