The Stream class supports the mixing of synchronous and asynchronous reads and writes on the same stream, regardless of whether the operating system allows this. Stream provides default implementations of asynchronous read and write operations in terms of their synchronous implementations, and provides default implementations of synchronous read and write operations in terms of their asynchronous implementations.
When implementing a subclass of Stream, it is necessary to provide an implementation for either the synchronous or asynchronous Read and Write methods. Overriding Read and Write is sufficient; the default implementations of the asynchronous methods (BeginRead, EndRead, BeginWrite, and EndWrite) will work with your implementation of the synchronous methods. Similarly, the synchronous Read and Write methods will work correctly if you provide an implementation of the asynchronous methods. The default implementations of ReadByte and WriteByte call the synchronous Read and Write methods with a one-element byte array. When subclassing Stream, if you have an internal byte buffer, it is strongly recommended that you override these methods to access your internal buffer for better performance.
A stream that connects to a backing store overrides either the synchronous or asynchronous read and write methods to get the functionality of the other by default. If a stream does not support asynchronous or synchronous operations, the implementer need only make the appropriate methods throw exceptions.