C# 在同一个流上启动多个异步读/写操作是否会损坏数据?
我使用异步I/O,因为它不会阻止调用线程,而是在后台执行线程处理。如果在同一个流上调用多个异步操作(如BeginWrite()),是否需要担心数据缓冲区内容混合在一起C# 在同一个流上启动多个异步读/写操作是否会损坏数据?,c#,multithreading,asynchronous,io,concurrent-programming,C#,Multithreading,Asynchronous,Io,Concurrent Programming,我使用异步I/O,因为它不会阻止调用线程,而是在后台执行线程处理。如果在同一个流上调用多个异步操作(如BeginWrite()),是否需要担心数据缓冲区内容混合在一起 122213121212122333313111223333 假设我要发送3个缓冲区: Buffer1: 1111111111 Buffer2: 2222222222 Buffer3: 3333333333 我不介意缓冲区是否以错误的顺序发送,所以 333333333311111111112222222222 可以,但缓冲区
122213121212122333313111223333
假设我要发送3个缓冲区:
Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333
我不介意缓冲区是否以错误的顺序发送,所以
333333333311111111112222222222
可以,但缓冲区内容是否可能完全混合在一起
122213121212122333313111223333
PS:我百分之百肯定已经有人以某种形式提出了这个问题……不,文件流不支持多个并发IO。Windows文件系统处理得不太好。它几乎肯定会抛出一个异常 编辑: 似乎表明文件系统将正确处理多个重叠的IO请求。我的错
但是,不要尝试在
文件流
上执行并发同步写入。这会引发异常。它取决于流的实现。例如,套接字支持多个重叠的读写请求,文件API也是如此。它们保证了每个操作的一致性(无交叉内容)以及操作顺序:例如,对于套接字读取,接收的字节将被放置在按发布顺序发布的缓冲区中。如果不提供这些保证,就不可能编写高性能网络应用程序,因为对于高性能网络IO,需要重叠发送,但实际上需要重叠接收。这一行为在许多文章中都有描述,包括“良好的ole”,并在MSDN上有记录:
发送和接收操作都可以
重叠。接收功能
可以多次调用以发布
接收缓冲区以准备
传入数据和发送功能
可以多次调用以排队
最多可发送多个缓冲区。注
当一系列的重叠发送
缓冲区将按顺序发送
提供,相应的完成
指示可能以不同的方式出现
秩序。同样,在接收
另一方面,缓冲区将填充在
订单他们是供应的,但是
完工迹象可能发生在一个特定的区域
不同的顺序
毫不奇怪,同样的担保也会延续到世界的管理端,例如:
读写操作可以是
在同一台计算机上同时执行
NetworkStream类的实例
不需要同步。
只要有一个唯一的线程
对于写入操作和一个
读取操作的唯一线程,
不会有交叉干扰
在读线程和写线程之间
需要同步
也就是说,在流上随机抛出异步读写将很快导致混乱。应用程序需要仔细编排线程提交操作的顺序,以便顺序是确定的。通常这意味着在(同步)列表中保留记帐,特别注意在保持同步锁的同时执行异步操作调用
最后一点需要注意的是,所有这些异步API都特别指出,不能保证完成顺序与提交顺序相匹配。3个缓冲区的发送顺序是否重要?如果数据以2222331111的形式发送,即没有交错,但顺序“不正确”怎么办?是的,类似的问题:我想你不应该这样做。MSND声明有关流对象的信息-不保证任何实例成员都是线程安全的。请务必阅读,特别是“同步完成I/O操作的另一个原因是操作本身。在Windows NT上,对文件执行的任何延长其长度的写操作都将是同步的”部分-1有足够的MSDN文档证明contrary@Remus:请提供链接。我的网站中有多个链接response@Remus:所有这些都提到Windows套接字,而不是文件API。我会去看看。所以基本上,如果我在调用BeginWrite时锁定网络流,我就不会有问题,并发运行的异步操作也不会相互冲突。