使用VS2017创建Xamarin Forms Master-Detail示例时,您将获得使用
等方法生成的MockDataStore类 public async Task<bool> DeleteItemAsync(string id)
{
var _item = items.Where((Item arg) => arg.Id == id).FirstOrDefault();
items.Remove(_item);
return await Task.FromResult(true);
}
说这是一个微软的例子,因此它必须是正确的。感觉很天真。
我不明白为什么这些方法不仅仅是return true
而且我没有看到这个成语解释过。我是否遗漏了一些微妙的内容,或者这是一个应该从模板中清除的历史性解决方法?
答案 0 :(得分:4)
我认为这背后的原因是为了防止“异步方法缺少等待运算符”编译器警告。这个自动生成的代码的作者想要标记函数async
,因为这是您在实现实际功能时将要做的事情。因此,为了防止编译器警告(没有自动生成的代码应该生成编译器警告),您需要等待一些东西,并且他们的代码中没有任何东西需要等待,所以他们选择等待Task.FromResult
。
当然,当您自己编写代码而不是自动生成代码以供将来编辑时 - 您不需要这样做。
答案 1 :(得分:0)
这个方法可能(应该)同步实现,因为它确实是真正的同步:
public bool DeleteItem(string id)
{
var _item = items.Where((Item arg) => arg.Id == id).FirstOrDefault();
items.Remove(_item);
return true;
}
将同步方法命名为* Async并返回Task<T>
毫无意义。
我猜你应该在那里添加你自己的异步删除逻辑。毕竟,生成的代码只是示例代码。
然后等待实际的数据库操作而不是Task.FromResult
(true),即用对执行数据库查询的方法的异步调用替换Task.FromResult(true)
,然后返回true
一旦异步方法成功返回。
答案 2 :(得分:0)
TL; DR:当函数返回Task
或Task<T>
时,它将异步处理。但它本身并不需要async
。
使用async
... await
表示编译器构建一个状态机来处理这个问题。但是,如果您等待的唯一事情是最后一个表达式,则可以避免使用此状态机:
public Task<bool> DeleteItemAsync(string id)
{
// Nothing awaitable here...
return Task.FromResult(true);
}
并创建一个同步运行的函数 - 但具有异步函数的签名和行为,因为它会对异步执行的操作进行调用。
为什么要返回Task<T>
:因为这就是调用者所期望的:如果不更改所有呼叫者,他们的呼叫者和他们的呼叫者,......就一直向下(可能),这是无法改变的。
因此签名无法更改。你必须返回一些等待的东西。但是你可以返回另一个结果的“可靠性”,如果这是你做的最后一件事(有点像实现尾递归)。
你得到一个MockDataStore
所以这只是用于测试:开销不太可能很重要,并且它提供的代码可以作为真实代码看起来像的一个很好的例子。 (比非常好 - 非常差 - 脚手架代码提供了一个不好的例子。)
注意:使用C#7时,使用ValueTask<T>
可以避免在立即知道结果时分配Task<T>
的开销。