Asp.net AppFabric/NCache-这些会解决通过引用更新的HttpRuntime.Cache对象吗?

Asp.net AppFabric/NCache-这些会解决通过引用更新的HttpRuntime.Cache对象吗?,asp.net,asp.net-mvc,caching,appfabric,ncache,Asp.net,Asp.net Mvc,Caching,Appfabric,Ncache,在ASP.NET应用程序中使用HttpRuntime.Cache时,从缓存中检索到的任何项目如果被更新,也会导致缓存对象被更新(通过引用)。从缓存中后续读取将获得更新的值,这可能是不需要的 关于这个主题有多篇文章,例如: object Get(string key) { if (!Cache.Contains(key)) { Cache[key] = GetDataFromDatabase(key); } return Cache[key];

在ASP.NET应用程序中使用HttpRuntime.Cache时,从缓存中检索到的任何项目如果被更新,也会导致缓存对象被更新(通过引用)。从缓存中后续读取将获得更新的值,这可能是不需要的

关于这个主题有多篇文章,例如:

object Get(string key) 
{ 
    if (!Cache.Contains(key))
    {
        Cache[key] = GetDataFromDatabase(key);
    }
    return Cache[key];
}

void Invalidate(string key)
{
    Cache.Remove(key);
}

建议的解决方案是使用二进制序列化创建深度拷贝克隆

二进制序列化的问题是速度太慢(难以置信的慢),我无法承受任何潜在的性能瓶颈。我已经研究过使用反射进行深度复制,虽然这看起来性能更好,但用我们复杂的DTO实现它并不是件小事。任何对此感兴趣的人都可能想看看下面的简短文章:

是否有人有过缓存解决方案(如AppFrabric/NCache等)的经验,并知道他们是否会直接解决此问题

提前谢谢


Griff产品(如NCache和AppFabric)在将对象存储到进程外缓存服务之前也会执行序列化。因此,您仍然会受到序列化的影响,另外,通过退出进程(甚至可能通过网络)访问缓存服务中的序列化对象,您的速度会进一步降低

在类上实现手动调优的深度拷贝将避免反射,并优于二进制序列化,但如果DTO非常复杂,这可能不实用

更新以提供详细信息:

AppFabric使用NetDataContractSerializer进行序列化(如上所述)。NetDataContractSerializer可以比BinaryFormatter快一点,但其性能通常是相同的:

NCache推出了自己的序列化程序,称为“紧凑序列化”。您需要在DTO类上实现它们的ICompactSerializable接口并手动读/写所有成员,或者让它们的客户机库检查您的类,然后在运行时发出自己的序列化代码来为您完成这项工作(当你的应用程序启动时,这是一次性的成功,他们必须对你的类进行反射并发出他们自己的MSIL)。我没有关于他们性能的数据,但可以安全地假设它比执行反射的序列化程序(BinaryFormatter/DataContractSerializer)更快可能与protobuf、MessagePack和其他避免过度反射的序列化程序处于相同的性能领域


(我在一家公司工作(ScaleOut软件)这与NCache在同一个领域,所以我可能应该知道更多关于它们是如何工作的。ScaleOut允许您插入您想要的任何序列化程序——我们通常会推荐,或者,因为它们通常被认为是.NET序列化性能的主要倡导者——如果您决定使用seriali,一定要仔细看看这两个

像NCache和AppFabric这样的产品在将对象存储到进程外缓存服务中之前也会执行序列化。因此,您仍然会受到序列化的影响,而且进程外(甚至可能通过网络)会进一步降低速度访问缓存服务中的序列化对象

在类上实现手动调优的深度拷贝将避免反射,并优于二进制序列化,但如果DTO非常复杂,这可能不实用

更新以提供详细信息:

AppFabric使用NetDataContractSerializer进行序列化(如上所述)。NetDataContractSerializer可以比BinaryFormatter快一点,但其性能通常是相同的:

NCache推出了自己的序列化程序,称为“紧凑序列化”。您需要在DTO类上实现他们的ICompactSerializable接口并手动读/写所有成员,或者让他们的客户端库检查您的类,然后在运行时发出自己的序列化代码来为您完成这项工作(当你的应用程序启动时,这是一次性的成功,他们必须对你的类进行反射并发出他们自己的MSIL)。我没有关于他们性能的数据,但可以安全地假设它比执行反射的序列化程序(BinaryFormatter/DataContractSerializer)更快可能与protobuf、MessagePack和其他避免过度反射的序列化程序处于相同的性能领域


(我在一家公司工作(ScaleOut软件)这与NCache在同一个领域,所以我可能应该知道更多关于它们是如何工作的。ScaleOut允许您插入您想要的任何序列化程序——我们通常会推荐,或者,因为它们通常被认为是.NET序列化性能的主要倡导者——如果您决定使用seriali,一定要仔细看看这两个大多数缓存框架都依赖于序列化

您应该考虑每次更改对象时使缓存无效。

例如:

object Get(string key) 
{ 
    if (!Cache.Contains(key))
    {
        Cache[key] = GetDataFromDatabase(key);
    }
    return Cache[key];
}

void Invalidate(string key)
{
    Cache.Remove(key);
}
因此,您可以:

var myDto = Get(id);
myDto.SomeProperty = "changed";
myDto.Save();
Invalidate(id);

大多数缓存框架依赖于序列化

您应该考虑每次更改对象时使缓存无效。

例如:

object Get(string key) 
{ 
    if (!Cache.Contains(key))
    {
        Cache[key] = GetDataFromDatabase(key);
    }
    return Cache[key];
}

void Invalidate(string key)
{
    Cache.Remove(key);
}
因此,您可以:

var myDto = Get(id);
myDto.SomeProperty = "changed";
myDto.Save();
Invalidate(id);

关于AppFabric和NCache序列化/反序列化的相对性能的任何信息?关于AppFabric和NCache序列化/反序列化的相对性能的任何信息?