Если бы Вы говорите на немецком языке, я предложил бы Вас открытая книга от Galileo Computing .
Ответ Кирка правильный. Перед созданием SPWeb у вас должен быть какой-то дескриптор для SPSite, и это тот же самый экземпляр SPSite, который будет у вас при вызове SPWeb.Site.
Давайте подумаем о последствиях этого - если вы не контролируете создание SPSite, но один из его дочерних веб-сайтов передается вам из внешнего кода, и вы удаляете сайт, когда управление возвращается вызывающему коду, вы удалили сайт, с которым они могут не работать! Поставьте себя на место вызывающего кода: вы передаете SPWeb в метод, и когда этот метод будет выполнен, используемый вами SPSite будет закрыт. Ответственность за очистку ресурсов, которые они выделяют, всегда лежит на создателе экземпляра. В этом случае не утилизируйте SPSite.
Просто обдумываю (иногда опасно) ...
Похоже, у вас не может быть SPWeb без SPSite. Итак, если вы получили SPWeb, не пройдя SPSite для его получения (либо создав новый SPSite, либо предоставленный вам), то вам, вероятно, не нужно беспокоиться об утилизации SPSite.
Это просто предположение, хотя. Хороший вопрос!
Вы пробовали проверить свою сборку с помощью SPDisposeCheck ? Возможно, это подскажет, как решить вашу проблему.
Это не ясно. Существует блог Стефана , в котором говорится : «Вам нужно убедиться, что вы удаляете только те объекты SPSite и SPWeb, которые принадлежат вашему коду» . Затем есть этот поток от Майкла Уошама (Microsoft), в котором утверждается, что этот шаблон действительно протекает.
Если вы не можете найти другую ссылку или кто-то еще не знает, почему бы вам не протестировать его на своем сервере разработки и добавить свои результаты в качестве ответа на этот вопрос? Поместите его в цикл, который выполняется 100 раз, и используйте ключ реестра SPRequestStackTrace, описанный в Устранение проблем с утечками SPSite / SPWeb в WSS v3 и MOSS 2007 , чтобы убедиться, что ваш тестовый код является источником проблемы.
Reflector сообщает нам, что это код, который запускается внутри объекта SPWeb, когда вы вызываете свойство Site:
public SPSite Site
{
get
{
return this.m_Site;
}
}
Он не создает новый объект SPSite, а просто возвращает тот, который у него уже был, о чем будет заботиться SPWeb.Dispose (), если это необходимо. Таким образом, вы можете безопасно использовать его, и я бы не стал избавляться от него, чтобы зависимости SPWeb не испортились вам.
Я часто использую этот шаблон в своем коде SharePoint в качестве практического правила, если вызов depose не приводит к сбою того, что я называю этим. Другое правило, которому я следую: я стараюсь не создавать расширения, которые не приводят к чистой прибыли в объектах SPRequest
(объект SPRequest
- это объект .net, который общается со всеми тяжелый вес com objcets)
теперь разбивает ваш пример
for (int i = 0; i < 100; i++)
{
using (SPWeb web = SPContext.Current.Site.OpenWeb(""))
{
SPSite site = web.Site;
Debug.WriteLine(site.Url);
}
}
Ключ здесь - SPContext.Current.Site
SPContext
будет очищен после него » s self правильно (один из немногих объектов, которые это делают), поскольку мы знаем, что сайт очищен правильно, я ожидаю, что веб-сайты были очищены до, однако это далеко не правильный ответ на ваш вопрос. (обратите внимание, что у вас должна происходить утечка веб-сайтов, полученных через OpenWeb)
public static void GetWebPartFromCatalog(this SPWeb web, string webPartName)
вам необходимо получить SPSite
для работы с веб-частями.
SPSecurity.CodeToRunElevated
Имея это в виду, я бы написал это как. . . теперь проверка Dispose в этом случае отключится, потому что SPSite передается в качестве аргумента, поскольку он не может отследить, в какой области он расположен.
public static void GetWebPartFromCatalog(this SPSite site, string webPartName) {
SPSecurity.CodeToRunElevated( () => {
using(SPSite suSite = new SPSite(site.Id)){
//do what you need to do
}
};
}
У Стефана Гобнера есть отличная статья по этому поводу: Устранение неполадок, связанных с утечками SPSite / SPWeb в WSS v3 и MOSS 2007
... И обязательно используйте инструмент проверки SPDispose в своей кодовой базе.