English 中文(简体)
Stream.Write 是否线程安全?
原标题:Is Stream.Write thread-safe?

我正在为一个遗留的RPC实现制作客户端/服务器库,但遇到了一些问题,当等待接收RPC请求消息的响应消息时,客户端有时会挂起。原来真正的问题是在我的消息帧代码中(当从底层NetworkStream读取数据时,我没有正确处理消息边界),但它也让我对我用于跨网络发送数据的代码感到怀疑,特别是在RPC服务器向客户端发送大量数据作为客户端RPC请求的结果的情况下。

我的发送代码使用 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 s的Write方法的调用)是原子的吗?也就是说,如果发送线程上仍在进行长时间的Write,并且心跳线程启动并发送一个PING消息,那么该线程会阻塞直到原始的Write调用完成,或者我必须在Send方法中添加显式同步以防止两个Send调用抵消了流?

最佳回答

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

Stream类中,所以没有保证。

问题回答

它没有被记录为原子操作。我不会假设它是,肯定会将那些东西放在一个定制的锁定机制中。基本上整个发送方法几乎要求锁定。

你应该将写入程序锁定在两个线程中以确保安全。我记得写入程序不是线程安全的。

请查看MSDN上的“Monitor”和“Mutex”。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签