ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c#-IMemoryCache保证唯一的新密钥.NET-Core

2019-11-11 17:15:01  阅读:481  来源: 互联网

标签:net-core caching c asp-net-mvc


我正在尝试使用Microsoft.Extensions.Caching.Memory.IMemoryCache接口/类.

我需要向缓存中添加一个新项目,并确保我不覆盖已保存的其他任何内容.目前,所有密钥都是自动生成并随机分配的(不是顺序的).

如何针对我当前的缓存项目测试随机密钥的唯一性?

或者,如何获得保证的唯一密钥?可以将自动生成的密钥用于以后的检索是可以的.

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory有几个示例,但是为我生成的每个键使用.TryGetValue(对象键,对象出值)来测试唯一性似乎有点过头,并且在考虑多线程环境时,这可能是个问题.

博客https://wildermuth.com/2016/04/14/Using-Cache-in-ASP-NET-Core-1-0-RC1对故意的Key使用相同的TryGetValue(key,out value)模式.

我希望不必将此生成密钥的列表保存在其他地方,即另一个列表分隔的列表,因为这会使我回到在列表变旧时修剪列表的问题.

另外,在这种特定情况下,我将密钥作为url-querystring参数传递,因此与url兼容的字符串将是超级.提前致谢.

解决方法:

正如您已经发现的,使用GUID作为缓存键不是一个好的解决方案.主要问题在于,在生成GUID之后,无法可靠地将其重新生成为相同的密钥,以便将数据从缓存中取出.

通常,当我创建一个缓存时,键是基于要缓存的实体或缓存它的方法.但是也可以根据使值唯一的值的组合来使高速缓存成为可能.

使用实体的例子

public class Employee
{
    int Id { get; set; }
    string Name { get; set; }
}

要从实体获取键,我们只需使用除实体主键之外的常量值即可.

private const string KEY_PREFIX = "Employee_";
private object syncLock = new object();

// innerEmployeeRetriever and cache are populated through the constructor
public Employee GetEmployee(int id)
{
    string key = KEY_PREFIX + id.ToString();

    // Get the employee from the cache
    var employee = cache[key];
    if (employee == null)
    {
        lock (syncLock)
        {
            // Double-check that another thread didn't beat us
            // to populating the cache
            var employee = cache[key];
            if (employee == null)
            {
                employee = innerEmployeeRetriever.GetEmployee(id);
                cache[key] = employee;
            }
        }
    }
    return employee;
}

使用方法名称的示例

private object syncLock = new object();

// innerEmployeeRetriever and cache are populated through the constructor
public Employee GetEmployeeList()
{
    string key = "GetEmployeeList";

    // Get the employee from the cache
    var employees = cache[key];
    if (employees == null)
    {
        lock (syncLock)
        {
            // Double-check that another thread didn't beat us
            // to populating the cache
            var employees = cache[key];
            if (employees == null)
            {
                employees = innerEmployeeRetriever.GetEmployeeList();
                cache[key] = employees;
            }
        }
    }
    return employees;
}

使用值组合的示例

您还可以根据使实体唯一的几个不同值来构建键.如果您没有要使用的主键,或者要单独缓存几个不同的上下文,这将很有帮助.这个例子取自MvcSiteMapProvider

protected string GetCacheKey(string memberName)
{
    // NOTE: We must include IsReadOnly in the request cache key 
    // because we may have a different 
    // result when the sitemap is being constructed than when 
    // it is being read by the presentation layer.
    return "__MVCSITEMAPNODE_" + this.SiteMap.CacheKey + "_" + this.Key 
        + "_" + memberName + "_" + this.IsReadOnly.ToString() + "_";
}

在这种情况下,我们将基于节点所属的父SiteMap的唯一键,节点的唯一键,方法或属性名称以及当前是否设置了只读标志来构建键.这些值的每个唯一集合都会导致一个单独的缓存键,从而为每个组合创建一个单独的缓存.

当然,要使其正常工作,值之间应存在某种“安全”定界符,以防止通过串联不同的值来创建相同的键.例如,“ 1”,“ 23”和“ 12”,“ 3”是相同的字符串,但是您可以通过使用下划线,竖线字符,逗号或其他一些不在分隔符中的定界符来防止此类冲突.数据本身以分隔值(“ 1”,“ _”,“ 23”和“ 12”,“ _”,“ 3”不是相同的字符串).

最重要的是,缓存键必须以某种方式表示缓存中的内容,以使其有用.您的应用程序应该了解如何提供构成密钥的数据,以便在需要再次检索相同数据时可以重新制作它.

标签:net-core,caching,c,asp-net-mvc
来源: https://codeday.me/bug/20191111/2021481.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有