C# 为什么返回等待任务。FromResult(true);而不是仅仅返回true?
当您使用VS2017创建Xamarin Forms Master Detail示例时,您将获得一个使用以下方法生成的MockDataStore类C# 为什么返回等待任务。FromResult(true);而不是仅仅返回true?,c#,async-await,C#,Async Await,当您使用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);
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);
}
公共异步任务DeleteItemAsync(字符串id)
{
var\u item=items.Where((item arg)=>arg.Id==Id.FirstOrDefault();
项目。删除(_项);
返回等待任务。FromResult(true);
}
说这是微软的一个例子让人觉得很幼稚,因此它一定是对的
我不明白为什么那些方法不只是返回true
,而且我还没有看到这个习惯用法的解释。这里是否缺少一些微妙的东西,或者这是一个应该从模板中清除的历史性解决方法?此方法可以(应该)同步实现,因为它确实是同步的:
public bool DeleteItem(string id)
{
var _item = items.Where((Item arg) => arg.Id == id).FirstOrDefault();
items.Remove(_item);
return true;
}
将同步方法命名为*Async并返回任务
,这是没有意义的
我想您应该在其中添加自己的异步删除逻辑。毕竟,生成的代码只是示例代码
然后,您将等待实际的数据库操作,而不是任务。FromResult
(true),即您将任务。FromResult(true)
替换为对执行数据库查询的方法的异步调用,然后在异步方法成功返回后返回true
。此方法可能(应该)以及同步实施,因为它确实是同步的:
public bool DeleteItem(string id)
{
var _item = items.Where((Item arg) => arg.Id == id).FirstOrDefault();
items.Remove(_item);
return true;
}
将同步方法命名为*Async并返回任务
,这是没有意义的
我想您应该在其中添加自己的异步删除逻辑。毕竟,生成的代码只是示例代码
然后,您将等待实际的数据库操作,而不是
Task.FromResult
(true),即替换Task.FromResult(true)
对执行数据库查询的方法进行异步调用,然后在异步方法成功返回后返回true
。TL;DR:当函数返回Task
或Task
时,它将被异步处理。但它本身不需要是async
使用async
…await
意味着编译器将构建一个状态机来处理此问题。但是,如果等待的只是最后一个表达式,则可以避免使用此状态机:
public Task<bool> DeleteItemAsync(string id)
{
// Nothing awaitable here...
return Task.FromResult(true);
}
公共任务DeleteItemAsync(字符串id)
{
//这里没有什么值得期待的。。。
返回Task.FromResult(true);
}
并创建一个同步运行的函数,但由于它对异步行为的调用,因此具有异步函数的特征码和行为
为什么返回任务
:因为这正是调用者所期望的:如果不一直(可能)更改所有调用者、调用者及其调用者,则无法更改此任务
因此签名无法更改。您必须返回可等待的内容。但如果这是您最后要做的事情,您可以返回另一个结果的“可等待性”(有点像实现尾部递归)
你会得到一个模拟数据存储
因此,这仅用于测试:开销不太可能很大,它提供的代码可以作为真实代码的一个很好的示例进行调整(比提供一个很差示例的框架代码要好得多)
注意:对于C#7,这是一个很好的例子,可以利用它来避免在立即知道结果时分配
任务的开销。TL;DR:当函数返回任务
或任务
时,它将被异步处理。但它本身不需要是异步的
使用async
…await
意味着编译器将构建一个状态机来处理此问题。但是,如果等待的只是最后一个表达式,则可以避免使用此状态机:
public Task<bool> DeleteItemAsync(string id)
{
// Nothing awaitable here...
return Task.FromResult(true);
}
公共任务DeleteItemAsync(字符串id)
{
//这里没有什么值得期待的。。。
返回Task.FromResult(true);
}
并创建一个同步运行的函数,但由于它对异步行为的调用,因此具有异步函数的特征码和行为
为什么返回任务
:因为这正是调用者所期望的:如果不一直(可能)更改所有调用者、调用者及其调用者,则无法更改此任务
因此签名无法更改。您必须返回可等待的内容。但如果这是您最后要做的事情,您可以返回另一个结果的“可等待性”(有点像实现尾部递归)
你会得到一个模拟数据存储
因此,这仅用于测试:开销不太可能很大,它提供的代码可以作为真实代码的一个很好的示例进行调整(比提供一个很差示例的框架代码要好得多)
注意:对于C#7,这是一个很好的例子,可以用来避免在结果立即已知时分配任务的开销。我想这背后的原因是为了防止“异步方法缺少等待运算符”“编译器警告。此自动生成代码的作者希望将函数标记为async
,因为在实现真正的功能时,无论如何都要这样做。因此,为了防止编译器警告(没有自动生成的代码会生成编译器警告),您需要等待一些东西,而它们的代码中没有什么可以等待的,因此它们选择等待任务。FromResult
当然,当您自己编写代码而不是为将来的编辑自动生成代码时,您不需要这样做。我想这背后的原因是为了防止“async method缺少等待运算符”编译器警告。此自动生成代码的作者希望将函数标记为async
,因为当