我有一个返回任务的异步方法。在下列情况下我是否需要退货?
public async Task UpdateProductSpecificationsAsync()
{
await _productRepository.UpdateProductSpecificationsAsync(); //Takes long time to execute
}
以下代码示例是否彼此等效?
public Task UpdateProductSpecifications()
{
_productRepository.UpdateProductSpecifications(); //Takes long time to execute
return Task.FromResult(0);
}
public Task UpdateProductSpecifications()
{
_productRepository.UpdateProductSpecifications(); //Takes long time to execute
return Task.CompletedTask;
}
我是否应该等待Task.TaskCompleted
?
答案 0 :(得分:3)
我有一个返回任务的异步方法。在下列情况下我是否需要退货?
async Task
方法相当于非异步void
方法。与非异步void
方法一样,async Task
方法无法返回任何内容。
那就是说,你的例子似乎很奇怪。如果你要在方法中做的就是等待其他一些异步方法,那么你根本不应该使用async
/ await
。只需直接返回Task
:
public Task UpdateProductSpecificationsAsync()
{
return _productRepository.UpdateProductSpecificationsAsync();
}
以下代码示例是否彼此等效?
定义“等效”。对我来说,他们绝对不是不等同于。第一个创建一个新的Task<int>
对象,并将该对象作为Task
返回。调用代码必须将其强制转换回Task<int>
以查看结果值。
第二个返回静态Task.CompletedTask
属性值,它是一个单例对象,每个进程只分配一次。调用者无法读取结果值。
调用者必须进行额外的工作才能直接观察这些差异,但至少,返回对单例对象的引用比每次创建新对象更有效。当然,这是否重要取决于您调用该方法的频率。
所有这一切,我不明白为什么在这种情况下,你不会像这样实现它(假设没有_productRepository
方法的真正异步版本):
public Task UpdateProductSpecificationsAsync()
{
return Task.Run(() => _productRepository.UpdateProductSpecifications());
}
然后你会得到实际的异步行为,这是调用者通常所期望的。您的版本会强制调用者等待查找的方法,就像它是异步的一样。恕我直言,写一个谎言代码是一个非常糟糕的主意。
我是否应该等待
Task.TaskCompleted
[原文如此]?
你的意思是直接?或者通过代码不知道它已被提交Task.CompletedTask
引用?我会假设前者,因为期望后者知道它正在做什么是不合理的。
这对我来说似乎是一个过于宽泛的问题。 任何情况?这是可以解释的。
那就是说,我会对这个问题说“不”。等待你知道的事情的重点是什么? await
不会回复给调用者,因为等待已经完成。这对我来说似乎是一种浪费。
我可以想象一个等待Task.CompletedTask
的场景,以达到一些其他所需的副作用。我见过比生产代码更奇怪的东西。但我不会推荐它。无论我们谈论什么假设的副作用,我都相信这不是一个记录在案的副作用,所以人们会依赖未来可能发生变化的无证实施细节。
不要写脆弱的代码。编写仅依赖于记录的行为的代码,并且只做有明显意义的事情。 (以及必然结果:如果你打破这个规则,至少要写一个非常详细的评论来解释你为什么编写奇怪的,脆弱的代码。)