我是否需要查询我选择不等待的 ValueTask 的 .Result 属性?
Do I need to query the .Result property of a ValueTask that I choose to not await?
假设我有一个 returns 类型 ValueTask
对象的方法,例如 ChannelReader
上的 WaitToReadAsync
方法。我可以通过三种方式使用此 ValueTask
。我可以:
- 直接等待
- 把它变成一个任务,然后等待它(
.AsTask()
)
- 查询
.Result
属性是否同步完成(如果.IsCompleted
是true
)。
关于第三种方法(在 ValueTask 上调用 .Result
),MSDN documentation 声明此 属性 只能查询一次。但是,这个 属性 有必要查询吗?换句话说,从不查询 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
属性 也没有被调用过。这样可以吗?
好问题。是的,如果您对结果或可能存储的 Exception
不感兴趣,则完全可以省略查询 ValueTask<T>
的 Result
属性任务里面。如果您愿意,也可以在 ValueTask
创建后完全忽略它,从而导致 so-called fire-and-forget 任务。任务仍然会完成,即使您没有保留它的任何引用。
一般来说,消费你的 ValueTask
是个好主意,可以通过 await
ing 或 AsTask
ing 或查询他们的 Result
(前提是它们已经完成)。通过使用 ValueTask
,您向底层实现发出信号,表明支持 IValueTaskSource<T>
实例可以重用。当异步方法无法同步完成时,重用 IValueTaskSource<T>
个实例是基于 ValueTask
的 API 避免内存分配的方式。
在您的示例中,您在创建 ValueTask
后立即查询 IsCompleted
属性,因此 ValueTask
在创建时未完成的可能性很小。因此,对于您的示例,上述建议仅具有理论价值。在创建时完成的 ValueTask
不受 IValueTaskSource<T>
实例的支持,因此在您的示例中不查询 Result
不会对性能产生影响。如果您在创建 ValueTask
.
后稍后查询 IsCompleted
属性,该建议将具有实用价值
假设我有一个 returns 类型 ValueTask
对象的方法,例如 ChannelReader
上的 WaitToReadAsync
方法。我可以通过三种方式使用此 ValueTask
。我可以:
- 直接等待
- 把它变成一个任务,然后等待它(
.AsTask()
) - 查询
.Result
属性是否同步完成(如果.IsCompleted
是true
)。
关于第三种方法(在 ValueTask 上调用 .Result
),MSDN documentation 声明此 属性 只能查询一次。但是,这个 属性 有必要查询吗?换句话说,从不查询 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
属性 也没有被调用过。这样可以吗?
好问题。是的,如果您对结果或可能存储的 Exception
不感兴趣,则完全可以省略查询 ValueTask<T>
的 Result
属性任务里面。如果您愿意,也可以在 ValueTask
创建后完全忽略它,从而导致 so-called fire-and-forget 任务。任务仍然会完成,即使您没有保留它的任何引用。
一般来说,消费你的 ValueTask
是个好主意,可以通过 await
ing 或 AsTask
ing 或查询他们的 Result
(前提是它们已经完成)。通过使用 ValueTask
,您向底层实现发出信号,表明支持 IValueTaskSource<T>
实例可以重用。当异步方法无法同步完成时,重用 IValueTaskSource<T>
个实例是基于 ValueTask
的 API 避免内存分配的方式。
在您的示例中,您在创建 ValueTask
后立即查询 IsCompleted
属性,因此 ValueTask
在创建时未完成的可能性很小。因此,对于您的示例,上述建议仅具有理论价值。在创建时完成的 ValueTask
不受 IValueTaskSource<T>
实例的支持,因此在您的示例中不查询 Result
不会对性能产生影响。如果您在创建 ValueTask
.
IsCompleted
属性,该建议将具有实用价值