Skip to content

fix: Add Task.Yield to prevent thread pool starvation with synchronous operations#309

Merged
thomhurst merged 3 commits into
mainfrom
fix/task-yield-for-sync-operations
Aug 10, 2025
Merged

fix: Add Task.Yield to prevent thread pool starvation with synchronous operations#309
thomhurst merged 3 commits into
mainfrom
fix/task-yield-for-sync-operations

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

When users provide synchronous blocking functions (e.g., Thread.Sleep followed by Task.CompletedTask), the library would experience severe thread pool starvation, leading to poor parallel performance.

This fix adds await Task.Yield() before invoking user-provided task factories to ensure:

  • Synchronous operations don't block the calling thread
  • Thread pool threads remain available for parallel processing
  • Consistent performance regardless of whether users provide async or sync operations

Performance improvements with this fix:

  • Direct Thread.Sleep: From timeout/unusable to ~20x speedup
  • Now matches performance of Task.Run wrapped operations

Added comprehensive performance tests to validate the improvements.

…s operations

When users provide synchronous blocking functions (e.g., Thread.Sleep followed by Task.CompletedTask),
the library would experience severe thread pool starvation, leading to poor parallel performance.

This fix adds await Task.Yield() before invoking user-provided task factories to ensure:
- Synchronous operations don't block the calling thread
- Thread pool threads remain available for parallel processing
- Consistent performance regardless of whether users provide async or sync operations

Performance improvements with this fix:
- Direct Thread.Sleep: From timeout/unusable to ~20x speedup
- Now matches performance of Task.Run wrapped operations

Added comprehensive performance tests to validate the improvements.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
thomhurst and others added 2 commits August 10, 2025 16:11
- Remove all IOBoundParallelAsyncProcessor classes as they're redundant with Task.Yield()
- Replace isIOBound flag with optional maxConcurrency parameter for better flexibility
- Add backward compatibility overloads to maintain binary compatibility
- Increase test delays to account for Task.Yield() overhead
- All 503 tests now passing

BREAKING CHANGE: ProcessInParallelForIO methods removed. Use ProcessInParallel(maxConcurrency) instead.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@thomhurst
thomhurst merged commit 1bd6b3f into main Aug 10, 2025
3 checks passed
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.

1 participant