Asked by:
wo threads in use but also shows warnings about migrations when is none

Question
-
User-183185495 posted
Something has been worrying me about my design of how I access the dbconext for I have been getting a couple of clashes saying that the dbcontext is in use by another thread. Also the message claims there is migrations to be run but their is def not the migrations are up to date. I am using asp.net 3.1 and Entity framework core 3.1.5
In My startup.cs I use the following to setup the context
services.AddDbContext<MISDBContext> (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
In my controller I inject it in the following way
private readonly MISDBContext _context; public MISObjectsController(MISDBContext context, IStringLocalizer<MISObjectsController> localizer, IStringLocalizer<SharedResource> sharedLocalizer, UserManager<ApplicationUser> userManager, IToastNotification toast) { _context = context; _sharedLocalizer = sharedLocalizer; _userManager = userManager; var list = _userManager.Users.Select(x => new SelectListItem() { Text = x.FirstName.ToUpperInvariant() + " " + x.LastName.ToUpperInvariant(), Value = x.Id.ToString() }).ToListAsync(); ViewBag.Users = list; _toast = toast; }
Then in some function I would use it as such but I also do this inside of view components and am wondering is that how things are clashing saying that there is two threads in process.
Something has been worrying me about my design of how I access the dbconext for I have been getting a couple of clashes saying that the dbcontext is in use by another thread. Also the message claims there is migrations to be run but their is def not the migrations are up to date. I am using asp.net 3.1 and Entity framework core 3.1.5 In My startup.cs I use the following to setup the context services.AddDbContext<MISDBContext> (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient); In my controller I inject it in the following way private readonly MISDBContext _context; public MISObjectsController(MISDBContext context, IStringLocalizer<MISObjectsController> localizer, IStringLocalizer<SharedResource> sharedLocalizer, UserManager<ApplicationUser> userManager, IToastNotification toast) { _context = context; _sharedLocalizer = sharedLocalizer; _userManager = userManager; var list = _userManager.Users.Select(x => new SelectListItem() { Text = x.FirstName.ToUpperInvariant() + " " + x.LastName.ToUpperInvariant(), Value = x.Id.ToString() }).ToListAsync(); ViewBag.Users = list; _toast = toast; } Then in some function I would use it as such but I also do this inside of view components and am wondering is that how things are clashing saying that there is two threads in process. [HttpPost] public async Task<IActionResult> AddToAuditTrail(string updateInfo) { var userId = GetCurrentTennantId().Result; var caseOfficer = _context.Users.Where(w => w.Id == userId.ToString()).FirstOrDefault(); Int32.TryParse(TempData.Peek("CaseId").ToString(), out int resultCaseId); MISAuditTrail _auditrail = new MISAuditTrail(); _auditrail.MISObjectId = resultCaseId; _auditrail.TennantId = userId; _auditrail.CreatedBy = caseOfficer.FirstName + caseOfficer.LastName.Substring(0, 1); _auditrail.Action = updateInfo; _auditrail.AuditType = (int)MISAuditTrail.AudItTypes.NOTES; _auditrail.CreatedDate = DateTime.Now; _auditrail.isActive = true; _auditrail.isDeleted = false; _context.Add(_auditrail); await _context.SaveChangesAsync(); _toast.AddSuccessToastMessage("You have added an update to the case"); return RedirectToAction("Edit", new { id = resultCaseId }); }
Thursday, August 6, 2020 8:26 AM
All replies
-
User475983607 posted
The DdContext scope is configured as transient which creates a new instance each time the DbContext is injected. Use Scoped which is the default.
Thursday, August 6, 2020 11:02 AM -
User-183185495 posted
So remove this from the connection string?
ServiceLifetime.Transient
The DdContext scope is configured as transient which creates a new instance each time the DbContext is injected. Use Scoped which is the default.
Thursday, August 6, 2020 8:15 PM -
User-183185495 posted
When I remove that I then get this which is why i set it to that mode following the article.
A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913
It Crashes at this code
public void GetUsersList() { List<SelectListItem> list = new List<SelectListItem>(); var items = _context.Users.Where(w => w.Id != GetCurrentTennantId().ToString()).Select(sm => new { Name = sm.FirstName + " " + sm.LastName, Id = sm.Id.ToString() }).ToList(); ViewBag.UserList = items; }
mgebhard
The DdContext scope is configured as transient which creates a new instance each time the DbContext is injected. Use Scoped which is the default.
Thursday, August 6, 2020 8:21 PM -
User475983607 posted
roguenidb
When I remove that I then get this which is why i set it to that mode following the article.Transient is not a good option for a DbContext because the context is created each time it is injected. That can cause a lot of overhead.
Your design either creates more than one instance of the DbContext in a single request, you could be missing an await somewhere, or the design is leaking the DbContext between requests. I assume GetCurrentTennantId() is the problem given the snippet of code but the problem could be elsewhere.
Thursday, August 6, 2020 8:35 PM