【问题标题】:Are Stream.ReadAsync and Stream.WriteAsync supposed to alter the cursor position synchronously before returning or after the operation completes?Stream.ReadAsync 和 Stream.WriteAsync 是否应该在返回之前或操作完成之后同步更改光标位置?
【发布时间】:2015-08-07 06:22:53
【问题描述】:

我一直在尝试实现一个支持ReadAsyncWriteAsyncStream,并且考虑到documentation 的简洁性,我很难理解如何正确地做到这一点。具体来说,关于流的光标位置。关于旧的 BeginRead 函数,herehere 也提出了类似的问题。该函数的文档似乎表明,在任何挂起的异步操作完成之前,不应再次调用 BeginRead

鉴于 BeginRead 现在已弃用 no longer recommended for new developmentStream 可能已进行了重大更改以实现新的 Async 功能,事情再次不明朗。 (编辑:通常这种警告意味着新函数是直接实现的,旧函数调用新函数,只是为了向后兼容而仍然存在,但这里的情况似乎并非如此)。

ReadAsyncWriteAsync 函数的定义使得它们不会将所需的读/写流位置作为它们的 Win32 counterparts 做(我认为这是一个非常糟糕的设计选择),而是依赖于流实现所持有的当前位置。如果满足以下两个条件之一,则该情况很好:

  1. ReadAsyncWriteAsync 必须获取当前光标位置以供操作使用,并在返回 Task 之前将其更新为操作完成(或根本不更新),或者
  2. 在完成之前的所有异步调用之前,不能调用 ReadAsyncWriteAsync

在这两个条件之外,调用者永远无法确定读取或写入发生的位置,因为挂起的异步操作可能会改变任何Seek 和调用ReadAsync 或@ 之间的流的位置987654343@。这些条件都没有记录为要求,所以我想知道它应该如何运作。

我的白盒测试似乎表明至少对于StreamFileStream 版本,流位置异步更新,这似乎表明第二个条件(只允许一个挂起的操作)仍然是是必需的,但这似乎是一个严重的限制(它肯定排除了任何类型的内部分散-收集实现)。

谁能提供任何关于旧的BeginRead 限制是否仍然适用于ReadAsync 的权威信息?

【问题讨论】:

  • 我认为设计背后的逻辑是,流本质上不是线程安全的;因此,在异步操作正在进行时访问它是没有意义的(仅仅因为操作是异步的,允许您的代码优雅地等待流读/写而不会阻塞,并不意味着玩是个好主意该操作正在进行时来自另一个线程的流)。
  • 鉴于ReadAsync 将读取未知数量的字节,它怎么可能在操作完成之前准确地更新位置?
  • 并发 IO,即使按顺序启动,也会导致同时调用回调。这是大多数流实现的竞争条件。所以一般情况下是不允许的。
  • @Damien_The_Unbeliever:说得好。我主要考虑的是总是可能的 FileStreams,但对于大多数其他流来说,你是绝对正确的。

标签: c# stream async-await filestream c#-5.0


【解决方案1】:

谁能提供任何关于旧的BeginRead 限制是否仍然适用于ReadAsync 的权威信息?

同样的限制适用于BeginReadReadAsync

旧的 APM 方法尚未被弃用。它们仍然受到完全支持,使用它们没有任何问题。但是,async 方法更容易使用,因此文档建议改用它们。

这些旧类上的所有这些async“重载”通常仍然包括调用BeginXXXEndXXX,或者最多两个选项都调用一个共享方法(例如FileStream.BeginReadAsync)。我从未见过任何代码(在框架中或其他地方)在 async 上具有 APM 包装器方法。

因此,calling ReadAsync will result in calling BeginRead 因此任何限制都适用于两者。此外,由于Stream 不是线程安全的,也没有宣传为并发安全的(略有不同),因此可以安全地假设您不能同时使用async 请求泛滥它。

【讨论】:

  • 在没有文档的情况下,我希望源代码中至少有一条注释表明此限制,但我想对原始源代码进行 30 分钟的研究就足够了.谢谢!
  • 我确实喜欢第 2023 行该函数中的这条评论:This code needs to be fixed.
猜你喜欢
  • 1970-01-01
  • 2017-06-08
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多