我正在开发一个由非营利组织共享的博客应用程序。我希望每个组织都能够更改自己的博客设置。我采用了单一模式(来自BlogEngine.net)并对其进行了修改。 (我知道它不再是单例模式。)我已经测试了这种方法,它似乎在开发环境中工作正常。这种模式是一种很好的做法吗?是否存在将其置于生产环境中时可能出现的问题?
public class UserBlogSettings
{
private UserBlogSettings()
{
Load();
}
public static UserBlogSettings Instance
{
get
{
string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString();
object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings;
if (cacheItem == null)
{
cacheItem = new UserBlogSettings();
HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, DateTime.Now.AddMinutes(1),
Cache.NoSlidingExpiration);
}
return (UserBlogSettings) cacheItem;
}
}
}
(为简洁起见,省略了部分代码。)
感谢您的帮助,评论等
答案 0 :(得分:5)
如果是每个会话,请将其存储在会话中,而不是存储在缓存中。
此外,你无缘无故地向上转播和向下转播:
object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings;
这将删除不需要的演员
UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings;
if (cacheItem == null)
{
cacheItem = new UserBlogSettings();
HttpRuntime.Cache.Insert(cacheKey, cacheItem, null,
DateTime.Now.AddMinutes(1),
Cache.NoSlidingExpiration);
}
return cacheItem;
答案 1 :(得分:3)
您需要使用锁定以避免可能的竞争条件:
private static Object lock_Instance = new Object ();
public static UserBlogSettings Instance
{
get
{
string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString();
UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings;
if (cacheItem == null)
{
lock (lock_Instance)
{
// need to check again in case another thread got in here too
cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings;
if (cacheItem == null)
{
cacheItem = new UserBlogSettings();
HttpRuntime.Cache.Insert(cacheKey, cacheItem, null,
DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration);
}
}
}
return cacheItem;
}
}
答案 2 :(得分:0)
我认为你的一般情况很好,但如果有必要,我会建议性能提升(我知道......在真正需要之前不要进行优化)。
我可能会用这样的方法实现这个来获取设置对象:
public static UserBlogSettings getSettings(string orgName, Cache cache) {
// do the same stuff here, except using the method parameters
}
原因是HttpContext.Current和HttpRuntime.Cache必须通过一些旋转来获取当前Session和Cache的句柄。如果你是从asp.net页面调用它,那么你已经掌握了这些东西。所以使用你已经拥有的那些而不是再次查找它们。