C
C#14mo ago
Sander

❔ variable refusing to increment

ive got a variable inside my blazor component that refuses to increment itself inside a while loop of a PeriodicTimer. a copy of my code (the file) with the relevant methods and fields is below, inside the screenshot you can see the result when im running this. any answer to help me understand what is going on here would be greatly appriciated
14 Replies
canton7
canton714mo ago
Have you tried to figure out which bit is causing the problem? 1. If you replace the await TriggerOnTimeSelect with something else (e.g. await Task.Delay(100)), does it still happen? 2. If you replace the await OnTimeSelect(selectedTimeOfDay); with something else, does it still happen? 3. If you don't bind sliderValue to the input, does it still happen?
TheRanger
TheRanger14mo ago
try this
async Task RunTimer()
{
while (await periodicTimer.WaitForNextTickAsync(updateTimerCancellationToken) && !updateTimerCancellationToken.IsCancellationRequested)
{
int localSliderValue = sliderValue;
Console.WriteLine($"");
Console.WriteLine($"before increment: {localSliderValue}");

localSliderValue++;
currentTimeInMinutes++;

Console.WriteLine($"after increment: {localSliderValue}");

await TriggerOnTimeSelect(DateTime.Now.Second);

Console.WriteLine($"after function call: {localSliderValue}");

sliderValue = localSliderValue;
}
}
async Task RunTimer()
{
while (await periodicTimer.WaitForNextTickAsync(updateTimerCancellationToken) && !updateTimerCancellationToken.IsCancellationRequested)
{
int localSliderValue = sliderValue;
Console.WriteLine($"");
Console.WriteLine($"before increment: {localSliderValue}");

localSliderValue++;
currentTimeInMinutes++;

Console.WriteLine($"after increment: {localSliderValue}");

await TriggerOnTimeSelect(DateTime.Now.Second);

Console.WriteLine($"after function call: {localSliderValue}");

sliderValue = localSliderValue;
}
}
i stumbled through similiar issues before usually because of async and using local variables usually fixes it
DΣX
DΣX14mo ago
try using the volatile keyword for these variables that are incremented
TheRanger
TheRanger14mo ago
bigthonk never heard of that keyword before
DΣX
DΣX14mo ago
Interlocked.Increment Method (System.Threading)
Increments a specified variable and stores the result, as an atomic operation.
DΣX
DΣX14mo ago
its just based upon an assumption that you are updating them from different threads which for some orderly reasons writes back the old value after increment. but its just a guess, and worth a try
canton7
canton714mo ago
Volatile shouldn't make any difference. It's not being updated from multiple threads at the same time, and awaits put in a memory barrier anyway
DΣX
DΣX14mo ago
what is your idea on why its not incrementing?
canton7
canton714mo ago
(and volatile isn't the answer to threading issues anyway: what it does is very nuanced and depends on the memory model of the platform, and the advice is not to use it) My guess is that it's something to do with the fact that it's bound to a control, and code is invoked when the control changes. Or maybe that OnTimeSelect which we can't see. Hence my suggestions Easy to test: remove the binding / call to OnTimeSelect, see if the field starts behaving
TheRanger
TheRanger14mo ago
i would also change it to a property, then set a breakpoint on the setter to see what sets it back
DΣX
DΣX14mo ago
i wouldnt suggest using volatile either. was just a way to figure out if it is maybe thread related. as soon as you have await in some code, threads may not be the same anymore after is. so in each loop he may be in a different thread. the binding is a good call as well
Sander
SanderOP14mo ago
Thank you all for your replies, i'll test the things mentioned and come back with results
UltraWelfare
UltraWelfare14mo ago
I think the problem relies on the fact that none of the rerender rules apply so blazor doesn't rerender you can use statehaschanged 😛 inside runtimer or you can change your OnTimeSelect to be an EventCallback instead of a Func. However this will make the parent component rerender which might not be ideal for you... In the case where you only want to update this component use the statehaschanged as i've explained
Accord
Accord14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server