繁体   English   中英

这种修改过的C#单例模式是一种很好的做法吗?

[英]Is this modified C# singleton pattern a good practice?

我正在开发一个由非营利组织共享的博客应用程序。 我希望每个组织都能够更改自己的博客设置。 我采用了单一模式(来自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;
            }
    }
}    

(为简洁起见,省略了部分代码。)

感谢您的帮助,评论等。

如果是每个会话,则将其存储在会话中而不是存储在缓存中。

此外,你在这里无缘无故地向上转播和向下转播:

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;

您需要使用锁定来避免可能的竞争条件:

    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; 
        } 
    } 

我认为你的一般都很好,但如果有必要,我会建议性能提升(我知道......在你真的需要之前不要进行优化)。

我可能会用这样的方法实现这个来获取设置对象:

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页面调用它,那么你已经掌握了这些东西。 所以使用你已经拥有的那些而不是再次查找它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM