3

I have an async method which fetches some data from a DB using Entity Framework via an async call and just want to return that:

public async Task<List<Message>> GetMessagesAsync(string id)
{
   var user = await _dbContext.Users.Where(u.Id == id).AnyAsync();
   if (!user) 
      throw new ApplicationException();
   return  _dbContext.Messages.Where(m => m.Id == id).ToListAsync();
}

The DB query returns a Task to the desired result and I just want to return it without awaiting it here in this method. But the compiler does not allow that, giving me an error message saying

  [CS0266] Cannot implicitly convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Message>>' to 'System.Collections.Generic.List<Message>'. An explicit conversion exists (are you missing a cast?)

If I await the Db query in the last line, the code compiles just fine.

return await _dbContext.Messages.Where(m => m.Id == id).ToListAsync();

I do not understand, why it it necessary to do the await step here instead of doing it in the calling function lateron, when the data is actually needed.

mat
  • 1,645
  • 15
  • 36
  • Almost. That poster does have the same problem, but is talking about a choice between the two options. I do not have the choice, since the compiler prevents returning the Task directly. Maybe there was a related change in the C# standard. – mat Jan 02 '21 at 17:45
  • 2
    Remove the `async` keyword, and ditch the other operation that uses await? – Caius Jard Jan 02 '21 at 17:47
  • 1
    You may find this interesting: [Eliding Async and Await](https://blog.stephencleary.com/2016/12/eliding-async-await.html) – Theodor Zoulias Jan 02 '21 at 18:08
  • The `await` accomplishes two things, both very important: 1) suspends execution of the method, returning control to the caller, until the awaited object has completed, and 2) it unwraps the _result_ of the awaited object from the _task_ that represents that object. The unwrapping part is very important, even if there is no more logic left in the method to execute. See duplicates. – Peter Duniho Jan 02 '21 at 18:09
  • 1
    @mat There wasn't a change in the standard, it's just that you have another `await` in the method that you want to keep, so you cannot remove `async` from the method signature, and it then isn't "just a pass-through" method. Because of this situation, I would argue that you should keep the `await` for reasons stated in the Stephen Cleary's article. – GSerg Jan 02 '21 at 18:09

0 Answers0