4

I am trying to figure out what is the best way to select data via Entity Framework with async await. In the following code I have two options.

The first uses Task.FromResult.
The second option tries to use the async await keywords to optimize the code.

1.

public Task<IEnumerable<DesignExample>> ExecuteAsync(GetAllExamplesQuery query)
{
    var designExamples = _copyDataDb.DesignExamples.OrderBy(dE => dE.Order).Select(DesignExample.MapFromEntity);

    return Task.FromResult(designExamples);
}

2.

public async Task<IEnumerable<DesignExample>> ExecuteAsync(GetAllExamplesQuery query)
{
    var designExamples = await _copyDataDb.DesignExamples.OrderBy(dE => dE.Order).ToListAsync();

    return designExamples.Select(DesignExample.MapFromEntity);
}
  • Does the second option increase overall performance in relation to the first?
  • The second option will await the call to the database, but will that really give me any benefits in this scenario?
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
andreas
  • 505
  • 1
  • 7
  • 16
  • "Multiple active operations on the same context instance are not supported. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context." – Paul Zahra Aug 18 '14 at 10:12
  • @PaulZahra I'm not sure how that quote applies to my case? – andreas Aug 18 '14 at 10:18
  • The point basically being that to do database operations asynchronously is mighty dangerous. – Paul Zahra Aug 18 '14 at 10:24
  • @PaulZahra I don't really understand why and when it might be dangerous. Can you expand on this? – andreas Aug 18 '14 at 10:39
  • @PaulZahra I get it now. If I for example do another async call to the context without awaiting the first call I can get in trouble. – andreas Aug 18 '14 at 10:53

1 Answers1

14

These methods do two different things.

Your former executes a call to the DbContext synchronously and wraps the result in a Task. This means that the calling thread will not yield control back to the caller when making the call to the database. Consumers of this method may not understand why this ExecuteAsync is blocking their thread.

The latter, makes an asynchronous call using ToListAsync which frees the calling thread. This means the caller can do more work with the thread in the meantime, and execution will resume when the query finishes execution.

Does the second option increase overall performance in relation to the first?

In order to know that you will have to measure your code, this depends mainly on how long it takes to execute the query. Note that the use of async-await does have an overhead (although it is minimal for the gains of code readability) of generating a state-machine behind the covers. Note you cannot execute multiple queries to the same DbContext.

The second option will await the call to the database, but will that really give me any benefits in this scenario?

The main benefit of this will be that while the query runs, your thread will be free to do more work. In environments like ASP.NET, this means the ASP.NET ThreadPool is free to process more incoming requests in the meantime, it really depends on what you're trying to achieve.

There was a intriguing discussion on the use of async DB calls in Why does the EF 6 tutorial use asychronous calls? which i think you'll find interesting.

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321