Best practice - warning: method has no "wait" operator warning

Yes, I know there are other questions to understand what this warning means and how to resolve it, however I have a question about best practices regarding asynchronous programming.

I have a service layer that handles data transfer between the data layer and the presentation layer. This service contains several methods that query the database and return a result.

I am trying to use async programming wherever possible. Example:

    public async Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
    {
        return await Database.FindBy<SiteTemplateResource>(str => str.SiteTemplateId == siteTemplateId && str.HashedFile.EndsWith(extension)).ToArrayAsync();
    }

      

My problem is that I am not really expecting anything other than a call ToArrayAsync

, which I don't really need.

Should I go ahead and use async / await for this? And as I, for example, am waiting for something for this function:

    public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
    {
        return Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId;
    }

      

I am not expecting anything in this function, but I also do not need to call ToArrayAsync

, so how do I avoid the "method is missing" warning of waiting for the operator in the above case?

Thanks in advance.

+3


source to share


4 answers


If you don't have anything await

in a method that should be async

(for whatever reason), you can use Task.FromResult

what you might expect:

public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
{
    return await Task.FromResult(Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId);
}

      



If you don't need a method async

, you can just simply async Task<int>

replace it with int

.

+5


source


The Asynchornous api does not need the async \ await keywords. First you have to ask yourself, anything that you call inside your method uses IO and has an asynchronous version of that IO api. In your case you are trying to access the database, i.e. IO, your library has an async version ( ToArrayAsync

), so everything makes sense. Now check if you are doing anything else after calling the async api. If so, use async \ await. If not, return the result back to the caller:

public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
{
    return Database.FindBy<SiteTemplateResource>(str => str.SiteTemplateId == siteTemplateId && str.HashedFile.EndsWith(extension)).ToArrayAsync();
}

      

In the second case, you are also trying to access the database, but you think there is no async api for that. This is most likely not true, because if you have ToArrayAsync

- it is very likely that all database accessors are asynchronous, so you should have FirstAsync

. Then your method will look like this:



public async Task<int> SiteTemplateBySiteIdAsync(int siteId)
{
    var result = await Database.FirstAsync<SiteSiteTemplate>(sst => sst.SiteId == siteId);
    return result.SiteTemplateId;
}

      

This is where you are doing something after the call FirstAsync

, so you need to use the async \ await keywords.

+2


source


async/await

are needed only if you want to process the results of an already asynchronous operation in the method itself. They don't make an async method or call. If you don't need to process the result of the task, you can simply return it:

public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)
{
    return Database.FindBy<SiteTemplateResource>(str => 
                           str.SiteTemplateId == siteTemplateId 
                           && str.HashedFile.EndsWith(extension))
                   .ToArrayAsync();
}

      

or using the expressed method

public Task<SiteTemplateResource[]> GetResources(int siteTemplateId, string extension)=>
        Database.FindBy<SiteTemplateResource>(str => 
                        str.SiteTemplateId == siteTemplateId 
                        && str.HashedFile.EndsWith(extension))
                .ToArrayAsync();

      

In the second case, you can avoid async/await

and still keep it asynchronous if you use Where

Select and FirstAsync

:

public Task<int> SiteTemplateBySiteIdAsync(int siteId)=>
    Database.Where(sst => sst.SiteId == siteId)
            .Select(it=>it.SiteTemplateId)
            .FirstAsync();
}

      

This has the added benefit of returning only the ID from the database. If you didn't use Select

, the provider would have to read the entire object

+1


source


Maybe you can change your code like below:

public int SiteTemplateBySiteIdAsync(int siteId)
{
    return Database.First<SiteSiteTemplate>(sst => sst.SiteId == siteId).SiteTemplateId;
}

      

Have a nice day!

0


source







All Articles