Skip to content

End the run after repeated failed reads instead of spinning forever - #177

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/143-failing-read-loop
Sep 29, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/143-failing-read-loop

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #143

What changed

When stdin is redirected, Console.ReadKey throws InvalidOperationException on every call. ProcessInputAsync treated that as recoverable and retried immediately, so RunAsync never returned and kept one core at 100%.

  • The loop now counts consecutive failed reads. After MaxConsecutiveReadFailures (10) in a row, the exception propagates out of RunAsync. The existing finally still restores the cursor.
  • A successful read resets the count.
  • Exceptions thrown while handling input don't count toward the limit, so those errors behave as before.

Tests

New UIApplicationReadFailureTests:

  • AReadThatAlwaysFailsEndsTheRun: with a provider whose reads always fail, the run ends with InvalidOperationException within a bounded number of reads, and the cursor is visible again. Before the fix this failed because the run never ended. The test starts the run on the thread pool and cancels it on timeout, so a regression fails the test instead of hanging it.
  • AFewFailedReadsDoNotEndTheRun: two failed reads followed by an exit key still end the run normally.

The full suite passes (211/211).

🤖 Generated with Claude Code

https://claude.ai/code/session_01VCL6GX9wshgqiBeq6z98ZH


Generated by Claude Code

matt-edmondson and others added 2 commits September 29, 2026 12:55
…ver [patch]

With stdin redirected, Console.ReadKey throws InvalidOperationException on
every call. The input loop treated that as recoverable and retried at once,
so RunAsync spun a core at ~200k reads a second and never returned. Failed
reads are now counted, and after MaxConsecutiveReadFailures in a row the
exception propagates out of RunAsync, which restores the cursor as usual.
A successful read resets the count, and errors from handling input are not
counted.

Fixes #143

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCL6GX9wshgqiBeq6z98ZH
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UIApplication.RunAsync busy-loops at 100% CPU forever when stdin is redirected (≈200k failed ReadKey calls/sec)

1 participant