Технический ответ на исходный вопрос является квалифицированным «Нет»: все SPWeb
объекты, открываемые из SPSite
они автоматически уничтожаются, когда SPSite
расположен. Однако на практике неплохо распорядиться SPWeb
, как только вы закончите с этим, чтобы уменьшить давление памяти, особенно при работе с таким кодом, который открывает несколько объектов SPWeb
.
Реализация этого безопасного решения для LINQ на самом деле довольно проста в C#. Вы можете найти полную информацию в this post, но короткая версия - это то, что итератор C# может обрабатывать вас. С помощью моего метода AsSafeEnumerable()
расширения, ваш код относительно безопасным написано так:
using (SPSite spSite = Utility.GetElevatedSite(_rootUrl))
{
var sw = from SPWeb web in spSite.AllWebs.AsSafeEnumerable()
where web.ServerRelativeUrl.ToLower() == path
from SPWeb subWeb in web.Webs.AsSafeEnumerable()
select subWeb;
foreach(SPWeb aSubWeb in sw)
{
// Do something
}
}
Теперь результат вашего запроса, который я присвоенного sw
, ленивый итератор типа IEnumerable<SPWeb>
. Когда вы перечислите этот результат, каждый SPWeb
будет удален, когда перечислитель перейдет к следующему элементу. Это означает, что небезопасно использовать ссылку SPWeb
или любой созданный из нее объект SP * (SPList
и т. Д.), За пределами вашего цикла foreach
. Также sw
небезопасно использовать за пределами этого блока using
, потому что номер итератора будет привязан к теперь расположенному SPSite
.
Тем не менее, код, подобный этому, перечисляет все веб-страницы (дважды!), Является чрезвычайно дорогостоящим.Существует почти наверняка более эффективный способ, которым это может быть реализовано, если только с помощью spSite.AllWebs[path]
вместо from
/where
.
Что касается сборки мусора, эти объекты требуют удаления из-за неуправляемой памяти, выделенной для того, что GC даже не знает.
И, наконец, предостережение о вашей утилите GetElevatedSite. Если вы используете RunWithElevatedPrivileges
в своем вспомогательном методе, чтобы получить свой повышенный SPSite
, есть ряд проблем, с которыми вы могли столкнуться, вернув SPSite
из этого повышенного контекста. Если возможно, я бы предложил использовать олицетворение SPSite
- мой предпочтительный метод описан here.
Sahrepoint в сторону, я полагаю, что его невозможно рассеять внешние ресурсы при использовании linq вообще, правильно? – 2009-03-18 06:20:25
Дело с SharePoint заключается в том, что управляемая часть очень маленькая. Но экземпляры SPWeb и SPSite содержат ссылку на неуправляемый объект SPRequest, который может составлять 1-2 МБ. Когда GC не происходит достаточно быстро, у SharePoint заканчивается память. –
Я понимаю, что, когда мы используем LINQ с DataContext, вы удаляете весь файл данных после завершения LINQ с ним, который освобождает внешние ресурсы. Так что да, это будет мое предположение, что LINQ не собирается распоряжаться разработчиком. –