在此之前的操作完成之前,在此上下文中开始了第二次操作 [英] A second operation started on this context before a previous operation completed
问题描述
我有一个具有asp.net核心和实体框架核心的项目,出于性能原因,我使用MemoryCache. ForumQueryManager类用于查询论坛数据,而该类数据用于使用CacheManager的Get方法以及传递cachekey和timeout的缓存时间,以及一种用于确定何时缓存为空以从数据库中检索数据的方法.此代码几乎总是可以工作.但有时会抛出异常
I have a project with asp.net core and entity framework core, for performance reasons I use MemoryCache. ForumQueryManager class is for querying forum data and this class for data use CacheManager Get method and pass cachekey and timeout cache time and a method for when cache is empty for retrieving data from database. this code work almost always. but sometimes throw exception
例外:
处理请求时发生未处理的异常. InvalidOperationException:在此上下文上启动了第二个操作 在上一个操作完成之前.任何实例成员都不是 保证是线程安全的.
An unhandled exception occurred while processing the request. InvalidOperationException: A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
ForumQueryManager:
ForumQueryManager:
public class ForumQueryManager : IForumQueryManager
{
private readonly NashrNegarDbContext _dbContext;
private readonly ICalender _calender;
private readonly ICacheManager _cacheManager;
public ForumQueryManager(NashrNegarDbContext dbContext, ICacheManager cacheManager)
{
_dbContext = dbContext;
_cacheManager = cacheManager;
}
public async Task<List<ForumCategoryDto>> GetAll()
{
var items = await _cacheManager.Get(CacheConstants.ForumCategories, 20, GetForumCategories);
return items;
}
private async Task<List<ForumCategoryDto>> GetForumCategories()
{
var categories = await _dbContext.ForumCategories
.Select(e => new ForumCategoryDto
{
Name = e.Name,
ForumCategoryId = e.ForumCategoryId
}).ToListAsync();
return categories;
}
}
CacheManager:
CacheManager:
public class CacheManager: ICacheManager
{
private readonly IMemoryCache _cache;
private readonly CacheSetting _cacheSetting;
public CacheManager(IMemoryCache cache, IOptions<CacheSetting> cacheOption)
{
_cache = cache;
_cacheSetting = cacheOption.Value;
}
public async Task<List<T>> Get<T>(string cacheKey, int expirationMinutes, Func<Task<List<T>>> function)
{
List<T> items;
if (_cacheSetting.MemeoryEnabled)
{
var value = _cache.Get<string>(cacheKey);
if (value == null)
{
items = await function();
value = JsonConvert.SerializeObject(items, Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
_cache.Set(cacheKey, value,
new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(expirationMinutes)));
}
else
{
items = JsonConvert.DeserializeObject<List<T>>(value);
}
}
else
{
items = await function();
}
return items;
}
}
推荐答案
ForumQueryManager
必须是瞬态的,否则_dbContext
变量将被重用.
ForumQueryManager
must be transient, otherwise the _dbContext
variable will be reused.
这篇关于在此之前的操作完成之前,在此上下文中开始了第二次操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!