【问题标题】:How should I convert a function returning a non-generic Task to ValueTask?我应该如何将返回非泛型任务的函数转换为 ValueTask?
【发布时间】:2018-08-02 18:58:30
【问题描述】:

我正在编写一些代码,它在内存中构建一个缓冲区,然后在缓冲区填满时将其清空到 TextWriter 中。大多数时候,角色会直接进入缓冲区(同步),但偶尔(每 4kb 一次)我需要调用 TextWriter.WriteAsync

the System.Threading.Tasks.Extensions package 中似乎只有一个ValueTask<T> 结构,没有非泛型ValueTask(没有类型参数)。为什么没有ValueTask,如果我需要将返回非泛型Task(即void方法的异步等效)的方法转换为ValueTask,该怎么办?

【问题讨论】:

  • 您希望ValueTask 有什么行为?根据定义,当结果同步可用时,可以使用ValueTask。如果没有结果,返回 Task 有什么意义或好处?
  • @JSteward 我正在做一些事情,它在内存中构建一个缓冲区,然后在缓冲区填满时将其清空到 TextWriter 中。大多数时候,角色会直接进入缓冲区(同步),但偶尔(每 4kb 一次)我需要调用 TextWriter.WriteAsync
  • 我不确定您将如何从 ValueTask 中受益,但文档建议 对于使用结果以外的其他用途... ValueTask 可能会导致更复杂编程模型。也许您可以使用 TPL-Dataflow 之类的东西重新设计您的解决方案,它有多种缓冲和处理数据的方法。
  • @JSteward 感谢您的建议,但您不知道这一点,但对于我的目的而言,Dataflow 太过分了,尽管我很喜欢它。我希望这段代码快速而不是分配,我愿意使用复杂的编程模型来实现这一点:)

标签: c# async-await task task-parallel-library


【解决方案1】:

在黑暗中拍摄,但我认为这是因为Task.CompletedTask 对于大多数非通用情况来说已经足够了。

ValueTask<T> 视为Task<T>T 的联合(分别用于异步和同步情况)。因此,非泛型 ValueTask 将是 Task 的并集......什么都没有,所以只是 Task

我想不出非通用 ValueTask 与缓存已经完成的 Task (这是 Task.CompletedTask 是什么)实际上不同的情况,尽管我很想了解任何.

【讨论】:

  • 我不太同意非泛型ValueTask 与“只是一个任务”完全相同。更像Optional<Task> - 在操作同步完成的情况下,包装的Task 将为空。如果您在公式ValueTask<T> ~ T | Task<T> 中将T 设置为某个struct NoReturnValue {},您就会明白为什么会这样。我也许可以返回Task.CompletedTask,我回家后试试看
  • 我不清楚 Task 和空值之间的逻辑区别是什么(显然,实际上是后者抛出)。在这两种情况下,您都知道不要暂停执行,并且生成的状态机将在这样做之前检查IsCompleted
  • 是的,看起来这会奏效,感谢凯文的帮助。我担心async 方法可能总是构建一个新的Task,即使它同步完成,但从阅读AsyncTaskMethodBuilder 看来情况并非如此; async Task-returning 方法如果同步完成,则返回缓存的已完成 Task
  • 我确实认为不包含非泛型 ValueTask 是一个相当奇怪的 API 设计决定。你应该做什么并不明显。
  • Relevant new proposal添加一个非通用的ValueTask。如果您想重用异步情况下所需的分配,则有必要。
【解决方案2】:

基于this article,可以将任意异步方法直接从Task改为ValueTask,但一定要注意文中提到的它的使用模式;具体来说:

  • 多次等待实例。
  • 多次调用 AsTask。
  • 使用这些技术中的一种以上来使用实例。

如果您需要以Task / Task<TResult> 的形式返回结果,则应使用.AsTask()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多