Task.FromResult 可能返回单一实例
Task.FromResult<TResult>(TResult) 现在可能返回缓存的 Task<TResult> 实例,而不是始终创建新的实例。
旧行为
在以前的版本中,Task.FromResult<TResult>(TResult) 始终分配新的 Task<TResult>,而不考虑 T
的类型或结果值。
新行为
对于某些 T
类型和某些结果值,Task.FromResult<TResult>(TResult) 可能会返回缓存的单一实例对象,而不是分配新的对象。 例如,可能每次对 Task.FromResult(true)
的调用都将返回相同的已完成的 Task<bool>
对象。
引入的版本
.NET 6
中断性变更的类型
此项更改可能会影响二进制兼容性。
更改原因
许多开发人员预计 Task.FromResult<TResult>(TResult) 的行为与已经执行此类缓存的异步方法类似。 了解分配行为的开发人员通常会保留自己的缓存,以避免始终为这些常用值分配的性能成本。 例如:
private static readonly Task<bool> s_trueTask = Task.FromResult(true);
现在,Boolean 和小 Int32 值等值不再需要此类自定义缓存。
建议操作
除非使用引用相等性来检查一个 Task
实例是否与另一个 Task
实例相同,否则不应受到此更改的影响。 如果你使用此类引用相等性,并且需要继续此检查,请使用以下代码确保便始终返回唯一的 Task<TResult> 实例:
private static Task<T> NewInstanceFromResult<T>(T result)
{
var tcs = new TaskCompletionSource<T>();
tcs.TrySetResult(result);
return tcs.Task;
}
注意
这种模式比仅使用 Task.FromResult(result)
效率要低得多,除非你真的需要它,否则应该避免。
受影响的 API
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈