2

So im asking this question because I'm not sure which one of these options is the proper solution for staying async. I guess both will do the job, but still I want to be sure which one is the prefarable way:

Invoking method (stays the same)

  public async Task GetEntry(int id)
  {
     var entity = await _repository.GetByIdAsync(id)
  }

Option 1 : Repository Note: This option is not using the async modifier

  public Task<MyEntity> GetByIdAsync(int id)
  {
       return Query().SingleOrDefaultAsync(e => e.Id == id);
  }

  public IQueryable<MyEntity> Query()
  {
      return _dbContext.Set<MyEntity>().AsQueryable();;
  }

Option 2 : Repository (using await and the async modifier)

  public async Task<MyEntity> GetByIdAsync(int id)
  {
       return await Query().SingleOrDefaultAsync(e => e.Id == id);
  }

  public IQueryable<MyEntity> Query()
  {
      return _dbContext.Set<MyEntity>().AsQueryable();;
  }
Bumber
  • 59
  • 3
  • 6
    Stephen C says: [Eliding Async and Await](https://blog.stephencleary.com/2016/12/eliding-async-await.html) – Fildor Sep 09 '20 at 15:25
  • 1
    It's safe to exclude the `async\awat` in this case and thus reduce the overhead a little bit, but it's not always safe to do that, like if the async method call is inside a `using` or `try` block. – juharr Sep 09 '20 at 15:26
  • 1
    Related: [Any difference between “await Task.Run(); return;” and “return Task.Run()”?](https://stackoverflow.com/questions/21033150/any-difference-between-await-task-run-return-and-return-task-run) – Theodor Zoulias Sep 09 '20 at 21:41

1 Answers1

0

I reckon this will be closed as opinion based, so I'll give my opinion first:

2 & 3 appear to be using EF unconventionally (e.g. not using the DbSet in the context directly, but by type).

1 isn't using EF at all, but can be useful for unit testing as the actual database call is hidden away (although you can use an in-memory database for testing EF if you are using .net core, so this might be moot anyway).

You could argue that the first function in 2 is good because it's just returning a task without awaiting (which saves a context switch).

One other thing to consider, is that even though EF supports async/await, each DbContext cannot be used by multiple tasks at the same time. You should get an exception if you try this. Of course, if each unit-of-work has a separate DbContext then that isn't an issue.

Neil
  • 11,059
  • 3
  • 31
  • 56
  • You seem to have misread the question. There are only 2 options. The first bit of code is how they call the method in options 1 and 2 and the question is all about whether you should remove async await when it's safe to do so. – juharr Sep 09 '20 at 15:30
  • Hi, thanks for the quick reply :) I just saw the answer from @juharr. Thats exactly the consideration that I have, if its a valid solution leaving out the async modifier + await on SingleOrDefaultAsync and just returning the task, in order to await for it on the invoking method – Bumber Sep 09 '20 at 15:33