Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Stream.Write thread-safe?

I'm working on a client/server library for a legacy RPC implementation and was running into issues where the client would sometimes hang when waiting to a receive a response message to an RPC request message. It turns out the real problem was in my message framing code (I wasn't handling message boundaries correctly when reading data off the underlying NetworkStream), but it also made me suspicious of the code I was using to send data across the network, specifically in the case where the RPC server sends a large amount of data to a client as the result of a client RPC request.

My send code uses a BinaryWriter to write a complete "message" to the underlying NetworkStream. The RPC protocol also implements a heartbeat algorithm, where the RPC server sends out PING messages every 15 seconds. The pings are sent out by a separate thread, so, at least in theory, a ping can be sent while the server is in the middle of streaming a large response back to a client.

Suppose I have a Send method as follows, where stream is a NetworkStream:

public void Send(Message message)
{
   //Write the message to a temporary stream so we can send it all-at-once
   MemoryStream tempStream = new MemoryStream();
   message.WriteToStream(tempStream);

   //Write the serialized message to the stream.
   //The BinaryWriter is a little redundant in this 
   //simplified example, but here because
   //the production code uses it.
   byte[] data = tempStream.ToArray();
   BinaryWriter bw = new BinaryWriter(stream);
   bw.Write(data, 0, data.Length);
   bw.Flush();
}

So the question I have is, is the call to bw.Write (and by implication the call to the underlying Stream's Write method) atomic? That is, if a lengthy Write is still in progress on the sending thread, and the heartbeat thread kicks in and sends a PING message, will that thread block until the original Write call finishes, or do I have to add explicit synchronization to the Send method to prevent the two Send calls from clobbering the stream?

like image 239
Mike Spross Avatar asked Mar 09 '10 07:03

Mike Spross


2 Answers

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

From Stream Class, so no it is not guaranteed.

like image 81
Adriaan Stander Avatar answered Oct 19 '22 19:10

Adriaan Stander


It is not documented as atomic. I would not assume it is and definitely would wrap that stuff around a custom locking mechanism. Basically the whole Send method pretty much asks for a lock.

like image 41
TomTom Avatar answered Oct 19 '22 20:10

TomTom