Yes, I agree that documentation should be clear that async processing needs to be bounded by time (so messages don't time out) as well as IsStarved().

As to the issue here, i wasn't quite clear. I was trying to talk through several options, but most were more talking about options for reslution and what i thought was ideal than the problem as is. 

The problem with this current diff (checking `messagesInFlight >= 85% of lastRdyCount`) is that it stalls in the synchronous case where messages come in one by one and are finished or requeued immediately. In those cases, `messagesInFlight` never exceeds 1, and this would not return True. 

The rest of the description was trying to talk through a check that i think would work, and would not be subject to stalls.

`if  conn.rdyCount <= conn.lastRdyCount * 0.15 || conn.messagesInFlight >= conn.rdyCount * .85` (ignoring some bounds checks for making sure you had a rdyCount to start with, etc)

I'm also realizing as i've written this, that there is an edge case on line 746 where it also needs to check messagesInFlight against rdyCount. Implementation here for `IsStarved()` should match that logic that actually does the ready count update. (really `reader.IsStarved()` should just be checking a `conn.IsStarved()` for each connection.