🔧 ProgrammierungWebKit Features for Safari 27.0(17.09.2026 um 13:30 Uhr)
🔧 ProgrammierungWebKit Features for Safari 27.0(17.09.2026 um 13:30 Uhr)
🔧 Programmierung 🕛 vor 8 Monaten 4 Min Lesezeit
0

The Blazor Closure Bug That Made All My Time Slots 24:00 🕛 🕛

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




🐛 The Mysterious Bug



I was building a conference room booking system in Blazor when I encountered a bizarre bug. My timeline component showed time slots from 6 AM to 11 PM, but whenever I clicked any time slot, it would always show 24:00 in the console.




CODE
// Console output - ALWAYS showed 24!
Time slot selected: 24:0
Start: 06-01-2026 00:00:00, End: 06-01-2026 01:00:00






The timeline looked correct visually, but every single button was broken. How could all buttons from 6 AM to 11 PM send "24" as the hour?






🔍 The Investigation Journey



My first assumptions were all wrong:





  1. Timezone issue? - Checked DateTime.Kind, UTC conversions


  2. DateTime parsing bug? - Added extensive validation


  3. Browser datetime-local bug? - Tested across browsers



After 3 hours of debugging, I added more logging:




CODE
private async Task OnTimeSlotClick(int hour, int minute)
{
Console.WriteLine($"[DEBUG] Clicked hour: {hour}");
// Always showed 24, regardless of which button!
}






The maddening part? The loop looked perfectly correct:




CODE
<!-- This SHOULD create buttons for hours 6-23 -->
@for (int hour = 6; hour < 24; hour++)
{
<button @onclick="() => OnTimeSlotClick(hour, 0)">
@hour:00 <!-- Shows 6:00, 7:00, 8:00... CORRECT! -->
</button>
}






Buttons displayed: 6:00, 7:00, 8:00... but all called OnTimeSlotClick(24, 0) when clicked!






💡 The Revelation: Closure Capture



The issue was closure capture - a classic C# gotcha that's especially tricky in Blazor!




CODE
// What's ACTUALLY happening:
for (int hour = 6; hour < 24; hour++)
{
// ❌ Captures the VARIABLE 'hour', not its VALUE!
button.Click += () => OnTimeSlotClick(hour, 0);
}

// When loop finishes: hour = 24
// ALL click handlers now reference hour = 24!






In C#, lambdas capture variables, not values. By the time any button is clicked, the loop has completed, and hour = 24 (the loop exits when hour < 24 is false).






🛠️ The Simple Fix That Worked



I changed from for to foreach with Enumerable.Range:




CODE
<!-- ✅ THIS WORKS! -->
@foreach (var hour in Enumerable.Range(6, 18)) <!-- 6 to 23 -->
{
<button @onclick="() => OnTimeSlotClick(hour, 0)">
@hour:00
</button>
}






Why this works: Each iteration of foreach creates a new variable in memory, while for reuses the same variable.






🔧 Alternative Solutions






1. Local Copy in Loop (Most Common Fix)






CODE
@for (int hour = 6; hour < 24; hour++)
{
var currentHour = hour; // ✅ Local copy
<button @onclick="() => OnTimeSlotClick(currentHour, 0)">
@currentHour:00
</button>
}









2. Method with Parameter






CODE
@for (int hour = 6; hour < 24; hour++)
{
<button @onclick="@(() => HandleHourClick(hour))">
@hour:00
</button>
}

@code {
private void HandleHourClick(int hour) // ✅ New parameter each call
{
OnTimeSlotClick(hour, 0);
}
}









3. Use @key to Force Re-renders






CODE
@for (int hour = 6; hour < 24; hour++)
{
<div @key="hour"> <!-- ✅ Forces new component instance -->
<button @onclick="() => OnTimeSlotClick(hour, 0)">
@hour:00
</button>
</div>
}









🎯 Why This Happens in Blazor Specifically



Blazor makes this bug more likely because:





  1. Event handlers are lambdas that execute later


  2. Component lifecycle delays execution until after render


  3. State changes trigger re-renders, changing captured variables


  4. Async nature means lambdas execute long after loop completes






📚 The Universal Lesson



This isn't just a Blazor problem - it's a closure capture issue that appears in:





  • JavaScript: Same issue with var in loops


  • C#: Any lambda in a loop


  • Java: Anonymous classes capturing loop variables


  • Python: Similar issues with default arguments



The rule: When creating lambdas/events in loops, ensure you're capturing values, not variables.






🤔 Debugging Tips for Similar Issues





  1. Add immediate logging in the lambda


  2. Test with hardcoded values to isolate the issue


  3. Check if it's a closure problem by creating local copies


  4. Remember: Loops with lambdas are always suspicious!






💭 Final Thoughts



This bug taught me that sometimes the simplest-looking code can have the most surprising behavior. What looks like a primitive int in a loop actually becomes a shared reference across all event handlers.



Have you encountered similar closure bugs? What's your favorite "it can't be that" debugging moment?






Discussion:




  • Have you been bitten by closure capture bugs?

  • What other Blazor gotchas have you encountered?

  • Share your favorite debugging stories!

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
2 Quellen
The amount of e-waste caused by AI is underestimated: we can’t only include the servers
1 Quelle
Crusoe raises $3.9B to build massive data centers and small modular “AI factories”
1 Quelle
GitHub Release: openai/codex vrust-v0.156.0-alpha.1 (18.09.2026)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten The Blazor Closure Bug That Made All My Time Slots 24:00 🕛 🕛

Thematisch verwandte Begriffe: Blazor, Closure, That, Made · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...