Skip to content

fix: Fix critical deadlock and hanging issues in async processors - #311

Merged
thomhurst merged 1 commit into
mainfrom
fix/deadlock-and-hanging-issues
Aug 10, 2025
Merged

fix: Fix critical deadlock and hanging issues in async processors#311
thomhurst merged 1 commit into
mainfrom
fix/deadlock-and-hanging-issues

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

Changes Made:

1. Fixed cancellation handling in EnumerableExtensions

  • Added proper CancellationToken support to ToIAsyncEnumerable method
  • While loop now properly responds to cancellation requests
  • Prevents infinite hanging when tasks don't complete

2. Fixed semaphore release bug in ParallelExtensions

  • Only releases semaphore if it was successfully acquired
  • Prevents SemaphoreFullException when cancellation occurs during WaitAsync
  • Tracks acquisition state properly in both ProcessAsync overloads

3. Removed unnecessary Task.Run wrapping

  • Eliminated redundant Task.Run in rate-limited processors
  • Removed Task.Run wrapping for already-async operations in ParallelExtensions
  • Fixed Task.Run + Task.Yield redundancy (just using Task.Yield where needed)

4. Improved unbounded processor implementations

  • AsyncEnumerableUnboundedParallelProcessor now truly unbounded (no artificial limits)
  • Trusts .NET ThreadPool to manage resources appropriately
  • Enhanced documentation warnings about resource risks
  • Maintains backward compatibility

5. Performance improvements

  • Removed wasteful counting/enumeration operations
  • Eliminated double context switching from Task.Run + Task.Yield
  • Let runtime handle thread pool scheduling optimally

These fixes address the critical issues identified in the deadlock analysis while maintaining the library's performance characteristics and backward compatibility.

🤖 Generated with Claude Code

## Changes Made:

### 1. Fixed cancellation handling in EnumerableExtensions
- Added proper CancellationToken support to ToIAsyncEnumerable method
- While loop now properly responds to cancellation requests
- Prevents infinite hanging when tasks don't complete

### 2. Fixed semaphore release bug in ParallelExtensions
- Only releases semaphore if it was successfully acquired
- Prevents SemaphoreFullException when cancellation occurs during WaitAsync
- Tracks acquisition state properly in both ProcessAsync overloads

### 3. Removed unnecessary Task.Run wrapping
- Eliminated redundant Task.Run in rate-limited processors
- Removed Task.Run wrapping for already-async operations in ParallelExtensions
- Fixed Task.Run + Task.Yield redundancy (just using Task.Yield where needed)

### 4. Improved unbounded processor implementations
- AsyncEnumerableUnboundedParallelProcessor now truly unbounded (no artificial limits)
- Trusts .NET ThreadPool to manage resources appropriately
- Enhanced documentation warnings about resource risks
- Maintains backward compatibility

### 5. Performance improvements
- Removed wasteful counting/enumeration operations
- Eliminated double context switching from Task.Run + Task.Yield
- Let runtime handle thread pool scheduling optimally

These fixes address the critical issues identified in the deadlock analysis while maintaining the library's performance characteristics and backward compatibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
@thomhurst
thomhurst enabled auto-merge August 10, 2025 17:02
@thomhurst
thomhurst merged commit 7254f25 into main Aug 10, 2025
3 of 4 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