在 ASP.NET 中使用静态变量而不是应用程序状态 [英] Using static variables instead of Application state in ASP.NET

查看:21
本文介绍了在 ASP.NET 中使用静态变量而不是应用程序状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算在 ASP.NET 中使用静态变量而不是应用程序状态,我想知道这是否是正确的方法:

[Global.asax.cs]...公共类全局:System.Web.HttpApplication{void Application_Start(对象发送者,EventArgs e){//在应用程序启动时运行的代码}...私有静态字典<字符串,对象>cacheItems = new Dictionary();私有静态对象储物柜 = new object();公共静态字典<字符串,对象>缓存项{得到{锁(储物柜){返回缓存项;}}放{锁(储物柜){缓存项 = 值;}}}public static void RemoveCacheItem(string key){cacheItems.Remove(key);}...}

如您所见,我使用自动创建的 Global.asax(和代码隐藏)文件.我添加了一些静态变量和方法.我可以以这种方式使用它们:

[一些 .cs 文件]foreach(KeyValuePair dictItem in Global.CacheItems){...

这是正确的方法还是我应该创建新类而不是现有的全局类?如果我应该创建新类,我该怎么做?在哪里?

解决方案

微软说的

<块引用>

ASP.NET 包括应用程序状态主要是为了与经典 ASP 以便更容易地将现有应用程序迁移到ASP.NET.建议您将数据存储在静态成员中应用程序类而不是在应用程序对象中.这个提高性能,因为您可以更快地访问静态变量比您可以访问应用程序字典中的项目.

参考:http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

我的经历

静态变量和应用程序状态的主要区别在于,应用程序状态在所有线程和池中都是相同的,而静态变量仅在每个池中是相同的.

经过新测试后,我发现应用程序状态变量与静态变量相同,它们只是引用应用程序上的静态变量,并且正如 Microsoft 所说的那样,它们只是出于兼容性原因而存在

如果您有 4 个池运行您的网站(网络花园),那么您有 4 组不同的静态内存.

您的代码

关于您的代码,您尝试访问字典数据的方式存在错误,并且您将在真实网络中出错.这部分代码是锁定完整字典的变量,但不锁定您在使用时将要进行的更改.

//这不足以操作您的数据!公共静态字典<字符串,对象>缓存项{获取 { 锁(储物柜){ 返回缓存项;} }设置 { 锁(储物柜){ cacheItems = value;} }}

例如,正确的方法是锁定所有添加/删除操作,直到您完成为止.

private static DictionarycacheItems = new Dictionary();私有静态对象储物柜 = new object();公共字典<字符串,对象>缓存项{获取{返回缓存项;}设置{缓存项=值;}}SomeFunction(){...锁(储物柜){CacheItems["VariableName"] = SomeObject;}...}

另一方面,当你操作应用程序状态的数据时,你需要使用它的globalApplication.Lock();Application.UnLock(); 例如

Application.Lock();Application["PageRequestCount"] = ((int)Application["PageRequestCount"]) + 1;Application.UnLock();

以一些结论结束:

避免应用程序状态,只在代码中使用静态变量.

I plane to use static variables instead of Application state in ASP.NET and am wondering if this is correct approach:

[Global.asax.cs]

...

public class Global : System.Web.HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup

    }

    ...

    private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
    private static object locker = new object();

    public static Dictionary<string, object> CacheItems
    {
        get
        {
            lock (locker)
            {
                return cacheItems;
            }
        }

        set
        {
            lock (locker)
            {
                cacheItems = value;
            }
        }
    }

    public static void RemoveCacheItem(string key)
    {
        cacheItems.Remove(key);
    }

    ...
}

As you can see I use automatically created Global.asax (and code behind) file. I've added some static variables and methods. I can use them after in this manner:

[some .cs file]
foreach(KeyValuePair<string, object> dictItem in Global.CacheItems)
{
    ...

Is this the right way or I should create new class instead of existing Global? If I should create new class how can I do that and where?

解决方案

What Microsoft says

ASP.NET includes application state primarily for compatibility with classic ASP so that it is easier to migrate existing applications to ASP.NET. It is recommended that you store data in static members of the application class instead of in the Application object. This increases performance because you can access a static variable faster than you can access an item in the Application dictionary.

reference : http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

My experience

The main different between static variables and Application state, is that the Application state is the same across all threads and pools, but the static is the same only per pool.

After new tests I see that the Application state variables are the same as static variables, and they just reference to a static variable on the application, and they just exist for compatibility reasons as Microsoft says

If you have 4 pools running your site (web garden) then you have 4 sets of different static memory.

Your code

About your code, you have bug for the way you try to access your dictionary data, and you will going to have errors in real web. This part of the code is lock the variable of the full Dictionary but not lock the change you going to make when you use it.

// this is not enough to manipulate your data !
public static Dictionary<string, object> CacheItems
{
    get { lock (locker) { return cacheItems; } }
    set { lock (locker) { cacheItems = value; } }
}

The correct approach is to lock all actions of add/remove until you done, for example.

private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
private static object locker = new object();
public Dictionary<string, object> CacheItems
{
    get{ return cacheItems; }
    set{ cacheItems = value; }
}

SomeFunction()
{
    ...
    lock(locker)
    {
        CacheItems["VariableName"] = SomeObject;
    }
    ...
}

From the other hand when you manipulate data on application state you need to use the global lock of it Application.Lock(); and Application.UnLock(); for example

Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"]) + 1;
Application.UnLock();

To close with some conclusion:

Avoid Application state and just use static variables on your code.

这篇关于在 ASP.NET 中使用静态变量而不是应用程序状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆