Stream.ReadAsync 和 Stream.WriteAsync 应该在返回之前或操作完成之后同步更改光标位置吗?
Are Stream.ReadAsync and Stream.WriteAsync supposed to alter the cursor position synchronously before returning or after the operation completes?
我一直在尝试实现支持 ReadAsync
和 WriteAsync
的 Stream
,考虑到 documentation, I'm struggling to understand how to do so properly. Specifically, with respect to the stream's cursor position. A similar question was asked here and here 对旧 BeginRead
的稀缺性] 功能。该函数的文档似乎表明 BeginRead
在任何挂起的异步操作完成之前不应再次调用。
鉴于 BeginRead
现在 已弃用 no longer recommended for new development 并且 Stream
可能已被显着改变以实现新的异步功能,事情是再次不清楚。 (编辑:通常这种警告意味着新函数被直接实现,旧函数调用新函数并且仍然存在只是为了向后兼容,但这里似乎并非如此)。
ReadAsync
和 WriteAsync
函数的定义使得它们不会像 Win32 counterparts 那样采用所需的 read/write 流位置(非常糟糕的设计选择在我看来),而是依赖于流实现的当前位置。如果满足以下两个条件之一,则这种情况很好:
ReadAsync
和 WriteAsync
必须抓取当前光标位置供操作使用,并更新它,就好像操作在 return 之前完成(或根本不更新) Task
或
- 在所有先前的异步调用完成之前,无法调用
ReadAsync
或 WriteAsync
。
在这两个条件之外,调用者永远无法确定读取或写入将发生的位置,因为挂起的异步操作可能会改变任何 Seek
和调用 ReadAsync
或 WriteAsync
。这些条件都没有记录为要求,所以我想知道它应该如何运作。
我的白盒测试似乎表明至少对于 Stream
的 FileStream
版本,流位置更新是异步的,这似乎表明第二个条件(只允许一个挂起的操作) 仍然是必需的,但这似乎是一个严重的限制(它肯定排除了任何类型的内部分散 - 聚集实现)。
任何人都可以提供关于旧 BeginRead
限制是否仍然适用于 ReadAsync
的权威信息吗?
Can anyone provide any kind of authoritative information as to whether the old BeginRead
limitation still applies to ReadAsync
or not?
相同的限制适用于 BeginRead
和 ReadAsync
。
没有弃用旧的 APM 方法。它们仍然得到完全支持,使用它们没有任何问题。但是,async
方法更易于使用,因此文档建议改用它们。
这些旧 类 上的所有这些 async
"overloads" 通常仍然包含调用 BeginXXX
和 EndXXX
或最多两个选项都调用共享方法(例如 FileStream.BeginReadAsync
)。我从未见过任何代码(在框架中或其他方面)在 async
之上具有 APM 包装器方法。
因此,calling ReadAsync
will result in calling BeginRead
所以任何限制都适用于两者。此外,由于 Stream
不是线程安全的,也没有宣称是并发安全的(这略有不同),因此可以安全地假设您不能同时用 async
请求淹没它。
我一直在尝试实现支持 ReadAsync
和 WriteAsync
的 Stream
,考虑到 documentation, I'm struggling to understand how to do so properly. Specifically, with respect to the stream's cursor position. A similar question was asked here and here 对旧 BeginRead
的稀缺性] 功能。该函数的文档似乎表明 BeginRead
在任何挂起的异步操作完成之前不应再次调用。
鉴于 BeginRead
现在 已弃用 no longer recommended for new development 并且 Stream
可能已被显着改变以实现新的异步功能,事情是再次不清楚。 (编辑:通常这种警告意味着新函数被直接实现,旧函数调用新函数并且仍然存在只是为了向后兼容,但这里似乎并非如此)。
ReadAsync
和 WriteAsync
函数的定义使得它们不会像 Win32 counterparts 那样采用所需的 read/write 流位置(非常糟糕的设计选择在我看来),而是依赖于流实现的当前位置。如果满足以下两个条件之一,则这种情况很好:
ReadAsync
和WriteAsync
必须抓取当前光标位置供操作使用,并更新它,就好像操作在 return 之前完成(或根本不更新)Task
或- 在所有先前的异步调用完成之前,无法调用
ReadAsync
或WriteAsync
。
在这两个条件之外,调用者永远无法确定读取或写入将发生的位置,因为挂起的异步操作可能会改变任何 Seek
和调用 ReadAsync
或 WriteAsync
。这些条件都没有记录为要求,所以我想知道它应该如何运作。
我的白盒测试似乎表明至少对于 Stream
的 FileStream
版本,流位置更新是异步的,这似乎表明第二个条件(只允许一个挂起的操作) 仍然是必需的,但这似乎是一个严重的限制(它肯定排除了任何类型的内部分散 - 聚集实现)。
任何人都可以提供关于旧 BeginRead
限制是否仍然适用于 ReadAsync
的权威信息吗?
Can anyone provide any kind of authoritative information as to whether the old
BeginRead
limitation still applies toReadAsync
or not?
相同的限制适用于 BeginRead
和 ReadAsync
。
没有弃用旧的 APM 方法。它们仍然得到完全支持,使用它们没有任何问题。但是,async
方法更易于使用,因此文档建议改用它们。
这些旧 类 上的所有这些 async
"overloads" 通常仍然包含调用 BeginXXX
和 EndXXX
或最多两个选项都调用共享方法(例如 FileStream.BeginReadAsync
)。我从未见过任何代码(在框架中或其他方面)在 async
之上具有 APM 包装器方法。
因此,calling ReadAsync
will result in calling BeginRead
所以任何限制都适用于两者。此外,由于 Stream
不是线程安全的,也没有宣称是并发安全的(这略有不同),因此可以安全地假设您不能同时用 async
请求淹没它。