public class ProductService
{
private readonly IDbContextFactory _factory;
public ProductService(IDbContextFactory factory)
=> _factory = factory;
public async Task GetByIdAsync(int id)
{
await using var context = await _factory.CreateDbContextAsync();
return await context.Products.FindAsync(id);
}
public async Task UpdateStockQuantityAsync(int id, int updateQuantity)
{
await using var context = await _factory.CreateDbContextAsync();
var product = await context.Products.FindAsync(id);
if (product is null) return;
product.Quantity += updateQuantity;
await context.SaveChangesAsync();
}
}
Noter que ProductService a deux méthodes, GetByIdAsync et UpdateStockQuantityAsync. Un exemple du DbContext la classe est créée localement dans chacune de ces méthodes. Supposons maintenant que vous disposiez de deux threads, T1 et T2, qui exécutent ces méthodes simultanément. Autrement dit, le thread T1 exécute le GetByIdAsync méthode pendant que le thread T2 exécute la UpdateStockQuantityAsync méthode. Étant donné que chacune de ces méthodes est exécutée de manière isolée, elles auront leurs propres informations de contexte, de connexion et de suivi des modifications, et il n’y aura pas d’état mutable, vous n’avez donc pas besoin d’implémenter la synchronisation des threads dans aucune de ces méthodes.
Considérez le code suivant qui exécute une opération de lecture et une opération de mise à jour dans deux tâches distinctes.
public static async Task RunMethodsInParallelAsync(ProductService productService)
{
Task readTask = productService.GetByIdAsync(1);
Task updateTask = productService.UpdateStockQuantityAsync(3, 5);
await Task.WhenAll(readTask, updateTask);
Product? product = await readTask;
}
Le Task.WhenAll La méthode exécute les deux tâches en parallèle et attend que les deux soient terminées. La raison pour laquelle cette approche est thread-safe et ne créera pas d’erreurs de concurrence est que chacune de ces deux méthodes crée sa propre méthode. DbContext instance en interne. Par conséquent, l’opération de lecture et l’opération de mise à jour utilisent des DbContext cas.
