可以在同一个Stream上启动多个异步读/写操作会破坏数据吗?

时间:2011-05-20 20:24:43

标签: c# multithreading asynchronous io concurrent-programming

我正在使用异步I / O,因为它不会阻塞调用线程并在幕后执行线程处理。如果我在同一个Stream上调用多个异步操作(如BeginWrite()),我是否应该担心数据缓冲区内容是否混合在一起?

我们假设我想发送3个缓冲区:

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

我不介意缓冲区的发送顺序是否正确,所以

333333333311111111112222222222

没问题,但缓冲内容是否可能完全混合在一起?

122213121212122333313111223333
PS:我100%肯定有人已经以某种形式问过这个......

2 个答案:

答案 0 :(得分:8)

这取决于Stream的实现。例如,套接字支持读取和写入的多个重叠请求,文件API也是如此。它们保证每个操作的一致性(没有交错内容)以及操作顺序:例如,对于套接字读取,接收的字节将被放置在发布的订单中发布的缓冲区中。如果不提供这些保证,则无法编写高性能网络应用程序,因为重叠的发送是期望的,但重叠的接收实际上必需用于高性能网络IO。许多文章都描述了这种行为,包括好的“Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports”,并在MSDN Overlapped Input/Output上有记录:

  

发送和接收操作都可以   重叠。接收功能   可以多次调用发布   接收缓冲区以备   传入数据和发送功能   可以多次调用队列   向上发送多个缓冲区。注意   虽然一系列重叠发送   缓冲区将按顺序发送   提供,相应的完成   适应症可能发生在不同的地方   订购。同样,在接收时   一边,缓冲区将被填充   订购它们,但是   完成指示可能发生在   不同的顺序。

毫不奇怪,同样的保证会延续到世界的管理方面,例如。 NetworkStream课程:

  

读写操作即可   同时进行   NetworkStream类的实例   无需同步。   只要有一个独特的线程   用于写操作和一个   用于读取操作的唯一线程,   不会有交叉干扰   读写线程之间没有   同步是必需的。

话虽如此,在Stream上随机抛出异步读写将导致混乱很快。应用程序需要仔细协调线程提交操作的顺序,以使订单具有确定性。通常这意味着在(同步)列表中将记帐保持特别小心,以便在保持同步锁时执行异步操作调用

最后要注意的是,所有这些异步API在调用 completion 的顺序并不保证与提交顺序相匹配时特别注意。

答案 1 :(得分:0)

不,文件流不支持多个并发IO。 Windows文件系统无法很好地处理。它几乎肯定会抛出异常。

编辑:

Synchronization and Overlapped Input and Output似乎表明文件系统将正确处理多个重叠的IO请求。我的坏。

但是,请勿尝试在FileStream上执行并发同步写入。 会抛出异常。