是的,我知道还有其他问题要涵盖此警告的含义以及解决方法,但是,我对异步编程的最佳做法有疑问。
我有一个服务层,用于处理数据层和表示层之间的数据传输。该服务包含几种查询数据库的方法,并返回结果。
我一直在尝试使用异步编程。一个例子:
public async Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
{
return await Database.FindBy<SiteTemplateResource>(str => str.SiteTemplateId == siteTemplateId && str.HashedFile.EndsWith(extension)).ToArrayAsync();
}
我的问题是,我实际上并没有等待任何事情,除了ToArrayAsync
电话,我不会 需要。
我应该继续使用async / await吗?我将如何为此函数等待任何事情:
public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
{
return Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId;
}
我不会等待该功能中的任何内容,但我也不需要拨打ToArrayAsync
,所以如何避免警告&#34;方法缺乏等待&#39; await& #39;操作员&#34;在上面的情况?
提前致谢。
答案 0 :(得分:5)
如果某个方法中await
没有任何内容async
(无论出于何种原因),您可以使用Task.FromResult
,这可以等待:
public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
{
return await Task.FromResult(Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId);
}
如果您不需要async
方法,则只需更多async Task<int>
并将其替换为int
。
答案 1 :(得分:2)
Asynchornous api不一定需要async \ await关键字。首先,您应该问自己,在方法中调用的内容是否使用IO并具有该IO api的异步版本。在您的情况下,您尝试访问数据库,即IO,您的库具有异步版本(ToArrayAsync
),所以一切都有意义。现在,在调用异步api后,检查是否还有其他。如果是 - 请使用async \ await。如果不是 - 只需将结果返回给调用者:
public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
{
return Database.FindBy<SiteTemplateResource>(str => str.SiteTemplateId == siteTemplateId && str.HashedFile.EndsWith(extension)).ToArrayAsync();
}
在第二种情况下,您还尝试访问数据库,但是认为没有异步api来执行此操作。很可能不是这样,因为如果你有ToArrayAsync
- 很可能所有数据库访问方法都有异步版本,所以你应该有FirstAsync
。然后你的方法变成:
public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
{
var result = await Database.FirstAsync<SiteSiteTemplate>(sst => sst.SiteId == siteId);
return result.SiteTemplateId;
}
您在调用FirstAsync
后执行某些操作,因此需要使用async \ _wait关键字。
答案 2 :(得分:1)
async/await
。它们不会使方法或调用异步。如果您不需要处理任务结果,您只需返回它:
public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
{
return Database.FindBy<SiteTemplateResource>(str =>
str.SiteTemplateId == siteTemplateId
&& str.HashedFile.EndsWith(extension))
.ToArrayAsync();
}
或者,使用表达方法
public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)=>
Database.FindBy<SiteTemplateResource>(str =>
str.SiteTemplateId == siteTemplateId
&& str.HashedFile.EndsWith(extension))
.ToArrayAsync();
如果您使用async/await
,选择并Where
:
FirstAsync
并保持异步
public Task<int> SiteTemplateBySiteIdAsync(int siteId)=>
Database.Where(sst => sst.SiteId == siteId)
.Select(it=>it.SiteTemplateId)
.FirstAsync();
}
这具有从数据库返回仅 ID的附加优势。如果您没有使用Select
,则提供者必须阅读整个对象
答案 3 :(得分:0)
也许你可以改变你的代码如下:
public int SiteTemplateBySiteIdAsync(int siteId)
{
return Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId;
}
度过美好的一天!