C# 异步编程的类型转换错误
有人能告诉我为什么这不起作用吗 我有一个方法如下所示:C# 异步编程的类型转换错误,c#,entity-framework,asynchronous,C#,Entity Framework,Asynchronous,有人能告诉我为什么这不起作用吗 我有一个方法如下所示: public virtual async Task<IList<User>> GetAll() { return this.db.Users.Where(model => model.CompanyId.Equals(this.companyId, StringComparison.OrdinalIgnoreCase)).ToListAsync(); } 公共虚拟异步任务GetAll() { 返回th
public virtual async Task<IList<User>> GetAll()
{
return this.db.Users.Where(model => model.CompanyId.Equals(this.companyId, StringComparison.OrdinalIgnoreCase)).ToListAsync();
}
公共虚拟异步任务GetAll()
{
返回this.db.Users.Where(model=>model.CompanyId.Equals(this.CompanyId,StringComparison.OrdinalIgnoreCase)).toListSync();
}
当我试图编译我的代码时,我得到一个错误声明:
错误10无法将类型“System.Threading.Tasks.Task>”隐式转换为“System.Collections.Generic.IList”。存在显式转换(是否缺少转换?)C:\Users\Jaymie\Documents\GitHub\Skipstone\Skipstone.Web\Repositories\UserRepository.cs 70 20 Skipstone.Web
但在它的正下方,我有一种方法:
public Task<User> FindByIdAsync(string userId)
{
return this.db.Users.Where(model => model.Id.Equals(userId, StringComparison.OrdinalIgnoreCase)).SingleOrDefaultAsync();
}
公共任务FindByIdAsync(字符串userId)
{
返回此.db.Users.Where(model=>model.Id.Equals(userId,StringComparison.OrdinalIgnoreCase)).SingleOrDefaultAsync();
}
这很好用
我想我看不见树木,所以需要其他人的眼睛来帮助我:)如果您使用的是async关键字,那么您需要使用wait关键字return original type
public virtual async Task<IList<User>> GetAll()
{
return await this.db.Users.Where(model =>
model.CompanyId.Equals(this.companyId,
StringComparison.OrdinalIgnoreCase)).ToListAsync().ConfigureAwait(false);;
}
公共虚拟异步任务GetAll()
{
return wait this.db.Users.Where(model=>
model.CompanyId.Equals(this.CompanyId,
StringComparison.OrdinalingOrecase().ToListSync().ConfigureAwait(false);;
}
或者如果没有async,您需要像在第二个正在工作的示例中那样指定类型Task ToListAsync方法返回一个
Task
对象,在您的情况下,该对象转换为Task
对象,但您方法的返回类型为Task
这里的问题是Task
中的T
不支持协方差
因此,您可以将方法的返回类型更改为Task
,或者自己编写代码进行转换:
return this.db.Users
.Where(model => model.Id.Equals(userId, StringComparison.OrdinalIgnoreCase))
.ToListAsync()
.ContinueWith<IList<User>>(t => t.Result, TaskContinuationOptions.ExecuteSynchronously);
返回this.db.Users
.Where(model=>model.Id.Equals(userId,StringComparison.OrdinalIgnoreCase))
.ToListAsync()
.ContinueWith(t=>t.Result,TaskContinuationOptions.ExecuteSynchronously);
啊,我明白了:)我觉得这很简单:D@r3plica:我将ExecuteSynchronously
参数添加到continuation,以减少continuation任务的开销。@JeanHominal您能解释一下同步添加ExecuteSynchronously的原因吗?我对整个同步/异步编程都是新手,并试图理解它。在我看来,您所做的是将异步方法转换为同步方法,这似乎很奇怪。即使您获得了性能,也失去了异步性。@MikeDymond:不,我没有将异步方法转换为同步方法。这里发生的是两个操作:第一,创建列表,第二,从原始任务
对象解包列表。ExecuteSynchronously
所做的是指定第二个任务相对于第一个任务同步执行-如果第一个任务异步执行,那么整个过程仍然异步运行。有关详细信息,请参阅。@JeanHominal谢谢,这真的很有帮助。希望我能发表评论:-)您的代码无法编译。如中所述,“异步方法的返回类型可以是Task
、Task
或void
”。是的,谢谢。我错过了。ScottChamberlain:实际上,使用async
和wait
将任务的结果从List
向IList
@SergeyLitvinov上传是为了将任务的结果从async
上传到IList
:另外,您还应该在调用toListSync()
之后使用-,在任务
对象上使用等待
时,如果不关心方法的其余部分是如何同步的,则应始终使用配置等待(false)
。(原因已解释)谢谢@JeanHominal的评论,我不知道。非常有趣的博客帖子!