Подтвердить что ты не робот

Использование статических переменных вместо состояния приложения в ASP.NET

Я планирую использовать статические переменные вместо состояния приложения в ASP.NET, и мне интересно, правильный ли это подход:

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

    ...
}

Как вы можете видеть, я использую автоматически созданный файл Global.asax(и код позади). Я добавил некоторые статические переменные и методы. Я могу использовать их следующим образом:

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

Правильно ли это, или я должен создать новый класс вместо существующего Global? Если я должен создать новый класс, как я могу это сделать и где?

4b9b3361

Ответ 1

Что говорит Microsoft

ASP.NET включает состояние приложения в первую очередь для совместимости с классический ASP, чтобы легче переносить существующие приложения на ASP.NET. Рекомендуется хранить данные в статических членах класс приложения, а не в объекте Application. Эта повышает производительность, потому что вы можете быстрее получить статическую переменную чем вы можете получить доступ к элементу в словаре приложений.

ссылка: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

Мое выживание

Основное отличие между статическими переменными и состоянием приложения заключается в том, что состояние приложения одинаково для всех потоков и пулов, но статичность одинакова только для каждого пула.

После новых тестов я вижу, что переменные состояния приложения такие же, как и статические переменные, и они просто ссылаются на статическую переменную в приложении, и они просто существуют по соображениям совместимости, поскольку Microsoft сообщает

Если у вас есть 4 бассейна, на которых работает ваш сайт (веб-сад), тогда у вас есть 4 набора различных статических памяти.

Ваш код

О вашем коде у вас есть ошибка для того, как вы пытаетесь получить доступ к своим данным в словарях, и у вас появятся ошибки в реальной сети. Эта часть кода блокирует переменную полного словаря, но не блокирует изменения, которые вы будете делать при использовании.

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

Правильный подход состоит в том, чтобы заблокировать все действия add/remove до тех пор, пока вы не сделаете это.

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

С другой стороны, когда вы манипулируете данными в состоянии приложения, вам нужно использовать global его блокировку Application.Lock(); и Application.UnLock(); например

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

Чтобы закрыть результат:

Избегайте состояния приложения и просто используйте статические переменные в вашем коде.