На веб-сайте ASP.NET, являются ли статические классы уникальными для каждого веб-запроса, или они создаются при необходимости, и GCed всякий раз, когда GC решает избавиться от них?
Причина, по которой я спрашиваю, состоит в том, что я написал несколько статических классов раньше в C #, и поведение отличается от того, что я ожидал. Я ожидал, что статические классы будут уникальными для каждого запроса, но, похоже, это не так.
Если они не уникальны для каждого запроса, есть ли способ позволить им быть?
ОБНОВЛЕНИЕ:
ответ, который дриса дала мне, был именно тем, в чем я нуждался. Я уже использовал одноэлементный класс, однако он использовал статический экземпляр и поэтому распределялся между запросами, даже если пользователи были разными, что в данном случае было плохо. Использование HttpContext.Current.Items
решает мою проблему отлично. Для тех, кто сталкивается с этим вопросом в будущем, вот моя реализация, упрощенная и сокращенная, чтобы было легко понять шаблон:
using System.Collections;
using System.Web;
public class GloballyAccessibleClass
{
private GloballyAccessibleClass() { }
public static GloballyAccessibleClass Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if(!items.Contains("TheInstance"))
{
items["TheInstance"] = new GloballyAccessibleClass();
}
return items["TheInstance"] as GloballyAccessibleClass;
}
}
}
filterContext.Result = new RedirectResult(...)
наперед : если вы перенаправите ваш запрос, скажем, с вами вы потеряете свои товары, потому что будет создан новый HttpContext. Более подробная информация здесь: stackoverflow.com/questions/16697601/…Ответы:
Ваши статические классы и поля статических экземпляров совместно используются всеми запросами к приложению и имеют то же время жизни, что и домен приложения. Поэтому вы должны быть осторожны при использовании статических экземпляров, поскольку у вас могут возникнуть проблемы с синхронизацией и тому подобное. Также имейте в виду, что статические экземпляры не будут подвергнуты GC до повторного использования пула приложений, и поэтому все, на что ссылается статический экземпляр, не будет GC. Это может привести к проблемам с использованием памяти.
Если вам нужен экземпляр с тем же временем жизни, что и у запроса, я бы предложил использовать
HttpContext.Current.Items
коллекцию. Это предназначено для хранения вещей, которые вам нужны по запросу. Для лучшего дизайна и удобочитаемости вы можете использовать шаблон Singleton, чтобы помочь вам управлять этими элементами. Просто создайте класс Singleton, в котором хранится его экземплярHttpContext.Current.Items
. (В моей общей библиотеке для ASP.NET у меня есть общий класс SingletonRequest для этой цели).источник
HttpContext.Current.Items
?"static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed"
- Есть ли источник для этого, потому что это не имеет никакого смысла и противоречит тому, что я читал в другом месте. Когда AppPool перерабатывается, соответствующий домен приложений полностью разрушается и GC'd. Когда это происходит, любые связанные статические экземпляры также будут GC'd, потому что их корень (AppDomain) исчез. В рамках перезапуска пула создается новый домен приложений и инициализируются связанные с ним статические экземпляры.Статические члены имеют область действия только текущего рабочего процесса, поэтому они не имеют ничего общего с запросами, поскольку разные запросы могут обрабатываться или не обрабатываться одним и тем же рабочим процессом.
Кстати, число рабочих процессов по умолчанию равно 1, поэтому в сети полно людей, которые думают, что статические члены имеют область действия всего приложения.
источник
Поскольку типы содержатся в домене приложения, я ожидаю, что статические классы будут присутствовать до тех пор, пока домен приложения не будет переработан или если запрос будет обслуживаться другим доменом приложения.
Я могу придумать несколько способов сделать объекты специфичными для конкретного запроса, в зависимости от того, что вы хотите сделать, например, вы можете создать экземпляр объекта в Application.BeginRequest и затем сохранить его в объекте HttpRequest, чтобы к нему могли обращаться все объекты в конвейер обработки запросов.
источник
Нет. Статические члены принадлежат процессу ASP.NET и доступны всем пользователям веб-приложения. Вам нужно будет обратиться к другим методам управления сеансом, таким как переменные сеанса.
источник
Обычно статические методы, свойства и классы являются общими на
Application
уровне. Пока приложение живет, оно является общим.Вы можете указать другое поведение, используя
ThreadStatic
атрибут. В этом случае они будут специфичны для текущего потока, который, я думаю, специфичен для каждого запроса.Я бы не советовал это, хотя это кажется слишком сложным.
Вы можете использовать,
HttpContext.Current.Items
чтобы настроить вещи для одного запроса, илиHttpContext.Current.Session
настроить вещи для одного пользователя (между запросами).В общем, хотя, если вам не нужно использовать такие вещи, как
Server.Transfer
лучший способ, это в основном создавать вещи один раз, а затем передавать их явно через вызов метода.источник