I understand what error is saying but unable to implement solution. I need to make a call to database (just to select) inside a method which would be called in thread.
I have searched through multiple answer for this and tried adding ServiceLifetime.Transient but got same result. Looks like something wrong in my DI.
I also have tried to pass Context in constructor to PriceSheetAsyncRepository but no luck.
public class PriceSheetRepository : IPriceSheetRepository
{
private readonly Pricing_PortalContext _context;
private readonly ILogger _logger;
public PriceSheetRepository(Pricing_PortalContext context, ILogger<PriceSheetRepository> logger)
{
_context = context;
_logger = logger;
}
public async Task<bool> ProcessPriceSheetImport(long ImportId)
{
var pricesheetAsyncRepo = new PriceSheetAsyncRepository(_logger);
foreach (var i in RequestList)
{
tasks.Add(Task.Run(async () => await pricesheetAsyncRepo.ValidatePublishAsync(i, _context)));
}
await Task.WhenAll(tasks);
}
}
public class PriceSheetAsyncRepository
{
private readonly ILogger _logger;
public PriceSheetAsyncRepository(ILogger logger)
{
_logger = logger;
}
public Task<bool> ValidatePublishAsync(PriceSheetImportModel i, MyDBContext _context)
{
return Task.Run(() =>
{
i.IsValid = true;
i.LinePart = i.LinePart?.ToUpper();
if (effDate != null && _context.MyTablePublish.Where(x => x.A == i.A).Any())
{
i.IsValid = false;
i.Message = i.Message + "Duplicate published record, ";
}
}
}
}
Can any one please point out what Am I doing wrong here?
Simply put - Entity Frameworks contexts are not thread safe and don’t allow multiple operations to run in parallel.
Transient works if you actually have different instances of your context. But in your case, you’re just using the context on multiple concurrent Tasks.
Either make your code single threaded (for loop with await inside instead of adding to a list of tasks and using Task.WhenAll) or create a new instance of the context per Task you want to use it with.
An example of the latter might look like this (note the removal of Task.Run - it's hurting you, not helping)