在上一個操作完成之前,在此上下文中開始第二個操作

asp.net-core entity-framework-core memorycache

我有一個asp.net核心和實體框架核心的項目,出於性能原因我使用MemoryCache。 ForumQueryManager類用於查詢論壇數據,此類用於數據使用CacheManager Get方法並傳遞cachekey和超時緩存時間以及用於何時緩存為空以從數據庫檢索數據的方法。這段代碼幾乎總是如此。但有時會拋出異常

例外:

處理請求時發生未處理的異常。 InvalidOperationException:在上一個操作完成之前,在此上下文中啟動了第二個操作。任何實例成員都不保證是線程安全的。

Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

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的:

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變量。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow