我正在處理傳統RPC實現的客戶端/服務器庫,並且遇到了等待接收RPC請求消息的響應消息時客戶端有時會掛起的問題。事實證明,真正的問題在於我的消息幀代碼(從底層NetworkStream
讀取數據時,我沒有正確處理消息邊界),但這也讓我懷疑我用來通過網絡發送數據的代碼,特別是在RPC服務器由於客戶端RPC請求而向客戶端發送大量數據的情況下。Stream.Write是線程安全的嗎?
我的發送代碼使用BinaryWriter
寫一個完整的「消息」到底層的NetworkStream
。 RPC協議還實現了心跳算法,RPC服務器每隔15秒發送一次PING消息。 ping由一個單獨的線程發出,因此,至少在理論上,可以在服務器正在將大量響應流式傳輸回客戶端時發送ping。
假設我有一個Send
方法如下所示,其中stream
是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();
}
因此,我已經是個問題,是調用bw.Write
(和暗示該呼叫到底層Stream
的Write
方法)原子?也就是說,如果在發送線程上仍然有很長的Write
正在進行,並且心跳線程開始併發送PING消息,該線程是否會阻塞,直到原始Write
調用完成,還是必須向Send
添加明確的同步方法來防止兩個Send
調用來阻止流?
我也看到了,但由於該免責聲明適用於BCL中的幾乎每一個類,因此我想知道是否可能存在'Stream'異常,我可能在文檔中的其他地方忽略了它。 – 2010-03-09 07:20:04
很抱歉,但並不是我所知道的。確保你把它交到你自己的手中,以確保這部分代碼是線程安全的。 – 2010-03-09 07:21:17
不需要抱歉;)。我同意在任何情況下添加明確的同步都是安全合理的。我只是好奇它是否已經「內置」到「Stream」中,因爲「線程安全」免責聲明並不打折。有時MSDN往往會含糊不清。 – 2010-03-09 07:27:55