我有一个Web应用程序,我想从数据库中提取用户设置并存储它们以进行全局访问。将数据存储在Singleton或Session对象中会更有意义吗?这两者有什么区别?
将数据存储为对象引用或将其分解为值类型对象(整数和字符串)是否更好?
答案 0 :(得分:11)
会话。这就是它的用途。会话存储在全局缓存(基本上是单例)中,由会话ID键入。这样,您只获得感兴趣的会话的数据。使用单例基本上会复制全局缓存,您必须重新发明机制以独立地检索每个会话的数据。
继续存储对象。让会话担心将其序列化为可以恢复的东西。但是,请注意您在会话中添加的内容。您不希望在那里存储太多数据,或者您将耗尽大量内存(假设内存缓存)。
答案 1 :(得分:4)
如果这些设置将用于站点的所有用户,请将它们放在单个或应用程序缓存中。如果它们特定于每个用户,请将它们放入会话中。
添加到应用程序或会话缓存时使用对象引用 - 我相信值类型将被装箱,因此它们看起来像缓存的对象。如果你使用单身,它可以采用任何一种方式。
答案 2 :(得分:2)
会话对象,当然。
单身人士存在于流程层面。这意味着如果您有20个用户在任何给定时刻访问您的网站,他们将使用相同的单一对象。如果你不经常进行网络开发,很难习惯这个概念。
会话存在于用户级别。这意味着您可以按用户存储数据,而不是按进程存储数据。
答案 3 :(得分:0)
有时我喜欢以下方法。它处理魔术字符串和未设置的会话变量的问题。它还在会话级别而不是应用程序级别运行单例。
public static SessionHandler GetInstance()
{
if (HttpContext.Current.Session["SessionHandler"] == null)
{
HttpContext.Current.Session["SessionHandler"] = new SessionHandler();
}
return (SessionHandler)HttpContext.Current.Session["SessionHandler"];
}
然后将其用作普通单身人士。输入你需要的变量。
答案 4 :(得分:0)
这是从旧文档中获取的,但它仍然非常有效并且有效...我会将链接内容放在这里,特别是因为它是一个可能会消失的旧链接。 Taken from here.
<强>背景强>
ASP.Net中的Session对象可用于存储特定于站点的单个用户的信息。会话由密钥名称索引,当以这种方式直接使用会话时,会导致大量的单个会话名称。另一种方法是改为创建单个对象以对相关项进行分组,并使用给定的键名存储该对象。 “singleton”是一种常见的设计模式,它指定如何确保任何时候只存在一个类的单个实例。
单身会话对象的优点
单身会话对象的缺点
更难以查看会话中单个项目的数量 ASP.Net Trace结果不显示对象内的值 使用进程外会话状态存储时的性能下降(影响序列化)
<强>实施强>
第一个实现步骤是创建一个类文件,该文件表示应该在单个对象中一起存储的项的逻辑分组。以下是演示该技术的示例类:
public class singleton
{
//Name that will be used as key for Session object
private const string SESSION_SINGLETON = "SINGLETON";
//Variables to store the data (used to be individual
// session key/value pairs)
string lastName = "";
string firstName = "";
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
//Private constructor so cannot create an instance
// without using the correct method. This is
// this is critical to properly implementing
// as a singleton object, objects of this
// class cannot be created from outside this
// class
private singleton()
{
}
// Create as a static method so this can be called using
// just the class name (no object instance is required).
// It simplifies other code because it will always return
// the single instance of this class, either newly created
// or from the session
public static singleton GetCurrentSingleton()
{
singleton oSingleton;
if (null == System.Web.HttpContext.Current.Session[SESSION_SINGLETON])
{
//No current session object exists, use private constructor to
// create an instance, place it into the session
oSingleton = new singleton();
System.Web.HttpContext.Current.Session[SESSION_SINGLETON] = oSingleton;
}
else
{
//Retrieve the already instance that was already created
oSingleton = (singleton)System.Web.HttpContext.Current.Session[SESSION_SINGLETON];
}
//Return the single instance of this class that was stored in the session
return oSingleton;
}
}
想要使用此对象的页面只执行以下操作:
singleton oSingleton = singleton.GetCurrentSingleton();
oSingleton.FirstName = "Robert";
oSingleton.LastName = "Boedigheimer";
通常,此技术将在给定类中存储更多变量,或者将用于执行过程的一系列网页。将其用于网站上的进程的另一个优点是,只需删除对单例对象的引用即可清除会话变量所需的所有内存。该类可以实现客户端可以用来清除引用的方法,当类提供清理方法时,可以将其命名为Dispose()以遵循典型的.Net模式:
public static void Dispose()
{
//Cleanup this object so that GC can reclaim space
System.Web.HttpContext.Current.Session.Remove(SESSION_SINGLETON);
}
<强>结论强>
使用存储在Session对象中的单例对象而不是使用单个会话密钥来存储信息有许多优点。它对于整个会话中存在的对象(分组逻辑项,影响分析,智能感知等)非常有用,特别是对于在网站上一段时间内真正需要的对象,直到用户完成特定对象过程(更容易识别错误使用变量并在过程完成但节点将继续时节省资源)。