ASP.NET Core Web API -How to resolve Warning CS1998 This async method lacks 'await' operators and will run synchronously

Viewed 34

I am implementing async programming in ASP.NET Core-6 Web API.

I have this code:

public async Task<IQueryable<Score>> GetExamScoreAsync(PagingFilter filter)
{
    var examScores = _dbContext.Scores
            .Where(m => (bool)m.Approval.IsFirstLevel == false)
            .Where(x => string.IsNullOrEmpty(filter.SearchQuery)
        || x.Subject.ToLower().Contains(filter.SearchQuery.ToLower())
        || x.StartDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture).Contains(filter.SearchQuery.ToLower())
        || x.EndDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture).Contains(filter.SearchQuery.ToLower()))
            .OrderByDescending(x => x.CreatedAt);
    return examScores;
}

I got this warning:

Severity Code Description Project File Line Suppression State Warning CS1998 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work

When I added await before _dbContext.Scores, I got this error:

Error CS1061 'IOrderedQueryable' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'IOrderedQueryable' could be found (are you missing a using directive or an assembly reference?)

How do I get this sorted out and apply async here?

Thank you.

1 Answers

You're not calling an asynchronous method that returns a Task/Task<T> so there's nothing to await (and not the right type to return). Update your method to what Artur suggested in their comment or make another call to generated the Task you're looking for (but you wouldn't need async and the result type wouldn't be IQueryable<T>. Some simplified possibilities:

public IQueryable<MyEntity> Get(...)
{
    return dbContext.MyEntities
        .Where(...);
}

public IAsyncEnumerable<MyEntity> Get(...)
{
    return dbContext.MyEntities
        .Where(...)
        .AsAsyncEnumerable();
}

public Task<MyEntity[]> Get(...)
{
    return dbContext.MyEntities
        .Where(...)
        .ToArrayAsync();
}

You would use async and await if you want to use the result of an asynchronous operation later in the same method:

public async Task<int> GetCount(...)
{
    var entities = await dbContext.MyEntities
        .Where(...)
        .ToArrayAsync();

    // obviously not efficient but to demonstrate
    // how async/await is used
    return entities.Length;
}
Related