
public class ProductService
{
personal readonly IDbContextFactory _factory;
public ProductService(IDbContextFactory manufacturing unit)
=> _factory = manufacturing unit;
public async Job GetByIdAsync(int id)
{
await utilizing var context = await _factory.CreateDbContextAsync();
return await context.Merchandise.FindAsync(id);
}
public async Job UpdateStockQuantityAsync(int id, int updateQuantity)
{
await utilizing var context = await _factory.CreateDbContextAsync();
var product = await context.Merchandise.FindAsync(id);
if (product is null) return;
product.Amount += updateQuantity;
await context.SaveChangesAsync();
}
}
Observe que ProductService tem dois métodos, GetByIdAsync e UpdateStockQuantityAsync. Uma instância do DbContext classe é criada localmente em cada um desses métodos. Agora, suponha que você tenha duas threads, T1 e T2, que executam esses métodos simultaneamente. Ou seja, a thread T1 executa o GetByIdAsync método enquanto o thread T2 executa o UpdateStockQuantityAsync método. Como cada um desses métodos é executado isoladamente, eles terão seu próprio contexto, conexão e informações de controle de alterações, e não haverá estado mutável, portanto, você não precisará implementar a sincronização de threads em nenhum desses métodos.
Considere o código a seguir que executa uma operação de leitura e uma operação de atualização em duas tarefas separadas.
public static async Job RunMethodsInParallelAsync(ProductService productService)
{
Job readTask = productService.GetByIdAsync(1);
Job updateTask = productService.UpdateStockQuantityAsync(3, 5);
await Job.WhenAll(readTask, updateTask);
Product? product = await readTask;
}
O Job.WhenAll O método executa as duas tarefas em paralelo e espera até que ambas terminem. A razão pela qual essa abordagem é segura para threads e não cria erros de simultaneidade é que cada um desses dois métodos cria seu próprio DbContext instância internamente. Portanto, a operação de leitura e a operação de atualização usam DbContext instâncias.