提问人:Boris B. 提问时间:11/6/2023 最后编辑:Theodor ZouliasBoris B. 更新时间:11/6/2023 访问量:100
如何在不使用 await 的情况下发布包装副作用的 ValueTask?
How to release a ValueTask that wraps a side-effect without using await?
问:
如果我有一个“无结果”的 ValueTask(如普通的 ,而不是 ValueTask<T>
)同步完成,则为 true。 尚未编辑。我如何告诉运行时我已经完成了 ,并且如果它恰好由 一个 支持,它可以被重用?
ValueTask
valueTask.IsCompletedSuccessfully
ValueTask
await
ValueTask
IValueTaskSource
ValueTask<T>
有一个属性,并且访问它(大概)标记为已消耗,但普通没有.Result
ValueTask<T>
ValueTask
Result
答:
0赞
Theodor Zoulias
11/6/2023
#1
可以通过调用 来通知基础 IValueTaskSource
对象 ValueTask
已被使用。GetAwaiter()
中。GetResult()
方法:
if (valueTask.IsCompletedSuccessfully)
{
valueTask.GetAwaiter().GetResult();
}
此调用不会导致任何分配。ValueTaskAwaiter
是一个结构。
对消费的影响没有记录在案。它只能通过研究相关类型(ValueTask、ValueTaskAwaiter
、ManualResetValueTaskSourceCore
)的源代码来派生。.GetAwaiter().GetResult()
ValueTask
谨慎:在任务完成之前调用 对于 不是有效的操作。此外,禁止多次调用 ,或与任何其他使用操作(如 或 AsTask
)同时调用。这些限制记录在结构的“备注”部分中。.GetAwaiter().GetResult()
ValueTask
.GetAwaiter().GetResult()
await
ValueTask
评论
0赞
Boris B.
11/6/2023
GetAwaiter()
“为此值创建一个等待者”,根据文档。如果我们已经知道它成功完成,那有必要吗?这难道没有违背 ValueTask 的目的吗?
1赞
Boris B.
11/6/2023
我刚刚花了最后 3 个小时浏览了消息来源,确实你是对的。内部方法 ,这是我需要的,只在 2 个地方公开:编译器生成的 awaiter 和(它只是委托给内部)。然而,直接在 getter 中具有相同的代码,而无需通过 awaiter。两者都在调用,这是实际负责“消耗”任务令牌的原因。ValueTask.ThrowIfCompletedUnsuccessfully
ValueTaskAwaiter.GetResult()
ValueTask.ThrowIfCompletedUnsuccessfully
ValueTask<T>
Result
IValueTaskSource.GetResult()
0赞
Charlieface
11/6/2023
你为什么不这样做呢?await
0赞
Boris B.
11/6/2023
@Charlieface因为我需要这个的方法不是.我不得不更改现有方法的实现,并意识到它没有等价物,并想知道如何向最终发出任务已被消耗的信号,因此我提出了我的问题。async
ValueTask
ValueTask<T>.Result
IValueTaskSource
评论