gpt4 book ai didi

C# 在缓存中存储值类型

转载 作者:行者123 更新时间:2023-12-04 17:55:58 25 4
gpt4 key购买 nike

问题

给定一个返回网站上活跃用户总数的函数:

private static readonly object Lock = new object();
public static int GetTotalActiveUsers()
{
var cache = HttpContext.Current.Cache;
if (cache["ActiveUsers"] == null)
{
lock (Lock)
{
if (cache["ActiveUsers"] == null)
{
var activeUsers = 5; // This would actually be an expensive operation
cache.Add("ActiveUsers", activeUsers, null, Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
}
}
}
return (int) cache["ActiveUsers"];
}

以这种方式在缓存中存储 ValueType 的问题是它不可更新。例如:

public static void OnNewActiveUser()
{
var total = GetTotalActiveUsers();
total++;
}

不更新缓存值。 (这是预期的行为)。

我正在寻找一种线程安全的方法来更新活跃用户数。

方案一

使用锁

public static void OnNewActiveUser()
{
lock (UpdateActiveUsersLock)
{
var cache = HttpContext.Current.Cache;
var newTotal = GetTotalActiveUsers() + 1;
cache.Insert("ActiveUsers", newTotal, null, Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
}
}

解决方案2

围绕 int 创建一个瘦类,将其转换为引用类型:

public class CachedInt
{
public int Int { get; set; }
public CachedInt(int value)
{
Int = value;
}
}

然后:

public static void OnNewActiveUser()
{
var activeUsers = GetTotalActiveUsers();
activeUsers.Int++;
}

问题

如果可能,我宁愿避免使用解决方案 1(它不太适合我的设计)。将值类型包装在薄类代码中是否有味道,还是解决问题的合法方法?

最佳答案

HttpContext.Current.Cache 缓存对象(引用类型),因此您需要按照您的建议将 int(值类型)包装在引用类型中。

如果缓存项永远不会过期,为什么不只使用一个带有静态方法和静态成员的类来进行计数呢?

此外,您应该使用互锁递增来确保计数正确,并通过某种方式了解用户何时不活跃,以便可以减少计数。正如评论中指出的那样,这只会为您提供单个进程的计数。如果您在同一台机器或多个服务器上有多个 Web 进程,则计数将是错误的 - 也许这就是返回 5 的昂贵操作:)

关于C# 在缓存中存储值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40344417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com