繁体   English   中英

C#/ ASP.NET-在会话中存储通用列表VS会话中的单个变量

[英]C#/ASP.NET - Storing Generic List in Session VS Individual Variables in Session

我已经看到了许多用于ASP.NET会话状态的“包装器”类,并且其中一些类似:

强类型层(伪代码#1)

public class MySession
{
    public int MyID
    {
        get
        {
            return Convert.ToInt32(HttpContext.Current.Session["MyID"]);
        }
        set
        {
            HttpContext.Current.Session["MyID"] = value;
        }
    }
    public string MyName
    {
        get
        {
            return (HttpContext.Current.Session["MyName"]).ToString();
        }
        set
        {
            HttpContext.Current.Session["MyName"] = value;
        }
    }
    ...

    public MySession()
    {
        // Could be static or instantiated depending on needs...
    }
    ...
}

///// USAGE IN OTHER CLASS /////

MySession currSession = new MySession();
currSession.MyID = 5;
currSession.MyName = "John Doe";

Console.WriteLine($"{currSession.MyName}'s ID = {currSession.MyID}");

然后我看到其他人做了类似的事情:

通用列表变体(伪代码#2)

public class SessionVariables
{
    public int MyID
    {
        get;
        set
        {
            MyID = value;
            MySession.SaveVariables();
        }
    }
    public string MyName
    {
        get;
        set
        {
            MyName = value;
            MySession.SaveVariables();
        }
    }

    ...
}

public class MySession
{
    public static List<SessionVariables> Variables;

    // Might be private in real application environment
    public MySession() // Could be static or instantiated depending on needs...
    {

        if (HttpContext.Current.Session["MyVariables"] == null)
        {
            HttpContext.Current.Session["MyVariables"] = new List<SessionVariables>();
        }

        // Obviously more appropriate checking to do here, but for simplicity's sake...
        Variables = (List<SessionVariables>)HttpContext.Current.Session["MyVariables"]

    }

    public static void SaveVariables()
    {
        HttpContext.Current.Session["MyVariables"] = Variables;
    }
    ...
}

///// USAGE /////

public class MyPage
{
    public void MyMethod()
    {
        MySession currSession = new MySession(); // Create variables

        MySession.Variables.MyID = 5;
        MySession.Variables.MyName = "John Doe";
        Console.WriteLine($"{MySession.Variables.MyName}'s ID = {MySession.Variables.MyID}");
        ...
    }
}

思考

显然,这些示例都是伪代码样式(因此请忽略一般错误),但是它们说明了一些为Session状态构建数据访问层的方法。

尽管具有更全面的数据类型映射/转换计划,但我还是执行与第一个变体相似的操作。 我使用一个“普通”类来包装Session,但是它很容易是静态的,因为属性将在调用它们的“ get”时从Session状态中拉出,因此永远不会不同步,因为该类实际上并不适用任何数据本身。

从我的第一印象来看,第二个对我来说似乎更“矫kill过正”,因为是的,您只在Session状态下存储了一个变量,但是通过强制代码引用列表,使其余代码杂乱无章:

myObject.TheList.VariableIWant
VS
myObject.VariableIWant

我更喜欢后者(看起来更干净),尽管可以很容易地将其隐藏在超类中或仅使局部变量直接引用该列表:

new MySession(); // Create the variables
List<SessionVariables> mySession = MySession.Variables;

...虽然乍一看对我来说似乎是肮脏的。 但是,我不知道使用列表存储实际上对代码/性能有多大好处,因为存储代表列表的对象所需要的内存应与分别处理每个变量一样多,至少这是我的想法。


从长远来看哪个更好的实践/维护成本低? 和/或哪个可以使网站获得更好的性能?

选项#1是我看到的最常见的模式,我使用它。 您可以使用常量而不是魔术字符串来改进它。 会话有问题,但制作一个完全无状态的应用程序也有问题。 我还建议使用HttpCache代替Session -它不会消耗AppPool资源。 但是,只要您使用SQL Server等会话提供程序,就只能在Web场上使用会话。 分布式缓存是另一回事。

使用选项1,很容易分辨出它在做什么。 您正在尝试标准化您的类如何保存/检索会话数据,而不是将其散布到各处。

选项2更加令人困惑。 实际上,我已经看了好几次了,我无法弄清楚列表上的内容。 为什么选项1不需要选项2时需要列表?

对于您要尝试执行的操作,选项1很好用。 常量不是一个坏主意,但是在这种情况下,我可能会跳过它。 字符串的含义非常明显,其他类不需要复制它,因为它们正在通过该类来访问Session。

选项1>选项2

两个原因:

  1. 使用Session.Remove删除会话变量后,应立即删除它们。 否则,您的会话状态将越来越大,并且您的Web服务器将无法支持那么多同时用户。 但是,如果所有变量都保存在一个大的会话变量中,则很难实现。

  2. 我会避免在会话中使用引用类型(例如,任何种类的List )。 它造成了歧义:如果您的会话存储在过程中,则该会话仅存储一个指针,并且您可以通过更改它们引用的对象更改会话变量,就像普通引用类型一样。 但是,如果您的会话超出proc(例如,使用状态服务器或SQL状态),则您的对象将被序列化和冻结,并且如果您更改所引用的对象,则这些更改将不会反映在您的会话变量中。 这可能会造成各种错误,这些错误只出现在您的上层环境中(如果您的开发系统缺少状态服务器),并且使您疯狂地尝试进行故障排除。

    您可能会为不可变的引用类型设置一个例外,但是您必须要小心; 仅仅因为对象是不可变的,并不意味着它引用的对象也是不可变的。

暂无
暂无

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

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