假设我有一个返回ValueTask类型对象的方法,例如ChannelReader上的WaitToReadAsync方法。有三种方法可以使用这个ValueTask。我可以:
.AsTask()).Result属性是否已同步完成(如果.IsCompleted为true)。关于第三个方法(在.Result上调用ValueTask),MSDN文档声明这个属性只能查询一次。但是,这个财产是否需要查询呢?换句话说,永远不要查询ValueTask的结果好吗?
这里是我的意思的一个例子:
var channel = Channel.CreateUnbounded<int>();
var waitToReadValueTask = channel.Reader.WaitToReadAsync(default);
if (waitToReadValueTask.IsCompleted)
{
if (channel.Reader.TryRead(out var result))
{
// Do something with the result object.
}
}在本例中,waitToReadValueTask从未被消耗过。它从未被期待,.Result的属性也没有被调用。这样可以吗?
发布于 2022-05-05 02:14:32
问得好。是的,如果您对结果不感兴趣,或者对任务中可能存储的Result不感兴趣,那么省略查询ValueTask<T>的ValueTask<T>属性是完全可以的。如果您愿意的话,在创建ValueTask之后完全忽略它也是可以的,从而导致所谓的火灾和遗忘任务。即使您没有保留任何参考资料,任务仍将完成。
一般来说,使用您的ValueTask是一个好主意,或者通过await对它们进行定义,或者通过AsTask对它们进行查询,或者通过查询它们的Result (前提是它们已经完成了)。通过使用ValueTask,您可以向底层实现发出信号,表示支持IValueTaskSource实例可以重用。在异步方法不能同步完成时,重用IValueTaskSource<T>实例是ValueTask-based API避免内存分配的方式。
在您的示例中,您将在创建IsCompleted之后立即查询ValueTask属性,因此创建ValueTask时不可能完成。因此,对于您的例子,上述建议只具有理论价值。创建时完成的ValueTask不受IValueTaskSource<T>实例的支持,因此不查询示例中的Result不会对性能产生影响。如果稍后在创建IsCompleted之后查询ValueTask属性,则该建议将具有实用价值。
https://stackoverflow.com/questions/72120361
复制相似问题