我一直试图实现一个支持Stream
和ReadAsync
的WriteAsync
,考虑到documentation的稀疏性,我很难理解如何正确地实现它。具体来说,相对于流的光标位置。关于旧的BeginRead
函数,也有类似的问题[AA>和here。该函数的文档似乎表明,在完成任何挂起的异步操作之前,不应再次调用BeginRead
。
考虑到BeginRead
现在已被弃用here并且Stream
可能已被显著更改以实现新的异步函数,情况再次变得不清楚。(编辑:通常这种警告意味着新的函数是直接实现的,而旧的函数调用新的函数,并且仅仅是为了向后兼容而存在,但这里的情况似乎并不完全如此)。ReadAsync
和WriteAsync
函数的定义使得它们不将所需的读/写流位置作为它们的no longer recommended for new developmentWin32do(我认为这是一个非常糟糕的设计选择),而是依赖流实现所保持的当前位置。如果两个条件之一成立,这种情况就可以了:ReadAsync
和WriteAsync
必须获取当前光标位置以供操作使用,并在返回Task
之前将其更新为操作完成(或根本不更新),或者
直到所有先前的异步调用完成为止,才能调用ReadAsync
或WriteAsync
。
在这两个条件之外,调用方永远不能确定读取或写入的位置会发生,因为挂起的异步操作可以改变流在任何Seek
和调用到ReadAsync
或WriteAsync
之间的位置。这两个条件都没有作为需求记录,所以我想知道它应该如何工作。
我的白盒测试似乎表明,至少对于FileStream
版本的Stream
,流位置是异步更新的,这似乎表明第二个条件(只允许一个挂起的操作)仍然是必需的,但这似乎是一个严重的限制(它当然排除了任何类型的内部分散收集实现)。
任何人都能提供关于旧的BeginRead
限制是否仍然适用于ReadAsync
的任何权威信息?
最佳答案
任何人都能提供关于旧的BeginRead
限制是否仍然适用于ReadAsync
的任何权威信息?
同样的限制也适用于BeginRead
和ReadAsync
。
旧的apm方法并没有被弃用。它们仍然得到充分的支持,使用它们没有任何问题。但是,async
方法更容易使用,因此文档建议使用它们。
这些旧类上的所有这些“重载”通常仍然包括调用async
和BeginXXX
或最多两个选项都调用共享方法(例如EndXXX
)。我从未见过任何代码(在框架中或其他方面)在FileStream.BeginReadAsync
中使用apm包装器方法。
因此,calling async
will result in calling ReadAsync
所以任何限制都适用于两者。此外,由于BeginRead
不是线程安全的,并且不做为同时安全的广告(这稍有不同),所以假定您不能同时使用Stream
请求来淹没它是安全的。