Can I use Async/Await with dbContext? If so, when should I use ConfigureAwait(false)?
.net, asynchronous, c#, entity-framework, multithreading
Solution
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.
Problem
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: - Whether or not I can use `async/await` with calls relating to dbContext - 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. - 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; } ```