SB2055 SB2055 - 1 month ago 15
C# Question

Can I use Async/Await with dbContext? If so, when should I use ConfigureAwait(false)?

Say I have the following snippet:

using (var db = new dbContext()){
var user = db.Users.Find(3);
user.Name = "newName";
var viewModel = GetViewModelAndDoStuffToUser(user);
db.SaveChanges();
return viewmodel;
}


Now I'm trying to improve the performance of this snippet at scale by leveraging async/await, but I've read that dbContext is not "thread safe". So I'm a bit confused about:


  1. Whether or not I can use
    async/await
    with calls relating to dbContext

  2. Whether or not I should use
    .ConfigureAwait(false)
    when I do. I've read that this tells us not to re-enter the ".NET Context" which is needed by MVC and WebApi controllers - but this is the service layer of an application serving those controllers. I've also read that using this will prevent deadlocks.

  3. Whether or not - in more complicated scenarios - I can parallelize calls using the same instance of
    dbContext
    by using
    Task.WhenAll()



Would the following snippet be a scalable, thread-safe step in the right direction?

using (var db = new dbContext()){
var user = await db.Users.FindAsync(3).ConfigureAwait(false);
user.Name = "newName";
var viewModel = await GetViewModelAndDoStuffToUserAsync(user).ConfigureAwait(false);
await db.SaveChangesAsync().ConfigureAwait(false);
return viewmodel;
}

Answer

Short answer is "Yes", "Yes", and "Yes".

Long answer is that although db context is not thread-safe, async/await constructs are not passing db context to other threads anyway, so you are safe here.

As far as the call to ConfigureAwait(false) goes, you should do it everywhere except UI code. Since database code is rarely placed in UI layer (it is never placed in UI level in high-quality production code) you should use ConfigureAwait(false) in every asynchronous call that you make on backend.

Finally, if you make multiple tasks with calls to async methods of db context, you create co-routines. They parallelize work outside your system (e.g. make concurrent DB calls), but on your end they are not running concurrently. This keeps your db context safe, because any changes to it are applied sequentially.

Comments