There is an output buffer for the child process, if it is not drained by the parent process than a blocking write by the child to stdout or stderr may cause the child to block until the output buffer is drained. This means the child process may never exit. Depending on how the buffering logic for the StreamReader is written it may never drain the output buffer of the child process because it is waiting to deliver at least buffer.Length bytes. If the parent always does a non-blocking read and always drains data from the output buffer of the child this dead-lock condition can be avoided. If we have a reliable repo of the dead lock, it should be easy to just change the older code to replace the ReadBlock with Read and see if this goes away. That is a much less invasive change than the current proposal.

In fact I believe the current proposed change still has this problem where the buffering logic may simply not drain the output buffer causing the child to block. To avoid all deadlocks it must be the case that there is no condition where the child is waiting for the parent to and the parent is waiting for the child. In this case the child is waiting for the parent to drain the buffer and the parent is waiting for the child to fill the buffer. Unless they both agree on the buffer size which I'm not sure is possible I see a possible deadlock. It safer for the parent to only block when there is zero data available rather than waiting for a minimum number of bytes or the child to close the pipe. 

A reliable repro would settle this, but it seems safer to err on the side of only blocking when there is no data rather than waiting for a minimum size of data being returned.