如果我在未定义为任务的 IQueryable 上使用 await + ToListAsync() 是不是正确

Posted

技术标签:

【中文标题】如果我在未定义为任务的 IQueryable 上使用 await + ToListAsync() 是不是正确【英文标题】:Is it correct if i am using await + ToListAsync() over IQueryable which is not defined as a task如果我在未定义为任务的 IQueryable 上使用 await + ToListAsync() 是否正确 【发布时间】:2015-12-21 23:24:00 【问题描述】:

我正在使用带有 EF-6 的 asp.net MVC-5,我不确定使用 await + ToListAsync 是否有效。例如,我有以下返回 IQueryable 的存储库方法:-

public IQueryable<TSet> getAllScanEmailTo()

    return t.TSets.Where(a=>a.Name.StartsWith("ScanEmail"));    

我这样称呼它:-

var emailsTo = await repository.getAllScanEmailTo().ToListAsync();

一开始,我以为我会得到一个错误,因为我正在使用“等待”一个没有定义为任务的方法,但上面的方法效果很好,所以请有人对此提出建议吗?

【问题讨论】:

【参考方案1】:

一开始我以为我会出错,因为我正在使用 “等待”一种未定义为任务的方法,但上述方法有效 不错

实际上,您正在等待一个返回Task&lt;T&gt; 的方法,其中TList&lt;TSet&gt;。如果您查看扩展方法QueryableExtensions.ToListAsync,您会看到它返回一个Task&lt;List&lt;TSource&gt;&gt;。您正在异步等待此方法来查询数据库、创建列表并将其返回给调用者。当您await 使用此类方法时,该方法在操作完成之前不会返回。 async-await 让您的代码感觉是同步的,而执行实际上是异步的。

【讨论】:

很好且完整的解释。 @Yuval 我已经意识到了这一点,但通常我在任务上使用等待,并且我的代码中的所有方法链都将是任务+等待.. 但因为我不能换行带有任务的 IQueryable 所以我这样做了,我正在使用 IQueryable --> await .tolistasync() ...所以这段代码是否会像 IQueryable 被包装在任务中一样工作?所以在我的情况下,iis 线程将被释放,直到 tolistasync() 完成执行,就像正常的 await 一样? @johnG 是的。该线程将在查询执行时被释放,并在查询完成后返回。 @johnG 如果你的方法同步执行,并返回一个Employee,那么你不能异步运行它,因为API本身是同步的。 @YuvalItzchakov 但如果我使用 SingleOrDefualtAsync 那么我可以获得单个员工异步吗?这是正确的吗?【参考方案2】:

实际上没有问题,因为您正在等待ToListAsync() 而不是getAllScanEmailTo()

编辑:要了解 async-await 模式的工作原理,您可以查看 link。这是一张有用的图片

【讨论】:

我的方法有效吗?否则将暂停执行,直到 IQueryable 的 ToListAsync() 方法完成。 是的,我非常了解这个执行路径,但我最初的问题是 await + Iqurable 如何协同工作。因为我不能在任务中包装 IQueryable ..所以我使用 await + ToListAsync() 但在非任务方法上,所以这会有任何副作用,或者我的代码将像我已经包装一样工作任务中的 IQueryable ??你明白我的意思了吗?【参考方案3】:

你不是在“等待一个方法”。您正在等待Task,这是一个可等待的。

您调用getAllScanEmailTo,返回一个IQueryable&lt;TSet&gt;,然后调用ToListAsync,返回您正在等待的Task&lt;List&lt;TSet&gt;&gt;

【讨论】:

所以像我正在做的那样使用 IQuerable 和等待是有效的吗?否则将暂停执行,直到 IQueryable 的 ToListAsync() 方法完成。 @johnG 是的。您正在等待Task,而不是IQueryable。是的,您将等待ToListAsync 完成。 但这样做会暂停执行,直到 IQueryable 的 ToListAsync() 方法完成 ?? @johnG 是的。 await 将异步等待操作完成。 @johnG 没有。当您等待异步操作时,线程被释放。

以上是关于如果我在未定义为任务的 IQueryable 上使用 await + ToListAsync() 是不是正确的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ME51n tcode 中的项目级别上使自定义字段可编辑?

SQL 维护计划在未配置邮件时发送邮件

错误 CS0012 类型“XmlReader”在未引用的程序集中定义

如何在未处理的任务异常上崩溃?

哪个更容易,编写自定义 OData uri 解析器或自定义 IQueryable 提供程序?

IQueryable 或 IList