It depends on the implementation of the Stream. For instance sockets support multiple overlapped requests both for read and for write, and so does the file API. They guarantee consistency of each operation (no interleaving content) and also order of operations: for instance for socket reads the bytes received will be placed in the buffers posted in the order posted. If these guarantees would not be provided it would impossible to write high performance network application, as overlapping Sends are desired but overlapping Receives are actually required for high performance network IO. This behavior is described in many articles, including good ole' Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports and is documented on MSDN Overlapped Input/Output:
Both send and receive operations can
be overlapped. The receive functions
may be invoked multiple times to post
receive buffers in preparation for
incoming data, and the send functions
may be invoked multiple times to queue
up multiple buffers to be sent. Note
that while a series of overlapped send
buffers will be sent in the order
supplied, the corresponding completion
indications may occur in a different
order. Likewise, on the receiving
side, buffers will be filled in the
order they are supplied, but
completion indications may occur in a
different order.
Not surprisingly, the same guarantees carry over to the managed side of the world, eg. the NetworkStream
class:
Read and write operations can be
performed simultaneously on an
instance of the NetworkStream class
without the need for synchronization.
As long as there is one unique thread
for the write operations and one
unique thread for the read operations,
there will be no cross-interference
between read and write threads and no
synchronization is required.
That being said, throwing randomly async reads and writes on a Stream will result in chaos pretty quickly. Applications need to carefully orchestrate the order in which threads submit the operations so that the order is deterministic. Usually this means keeping accounting in a (synchronized) list with special care to do the async operation invocation while holding the synchronization lock.
One final note is that all these async APIs make a special note in calling out that the order of completion is not guaranteed to match the order of submission.