Ну понятно, что если создаешь объекты SPSite и SPWeb их нужно уничтожить, и если все происходит в теле одного класса или в теле одной функции, то задача даже очень тривиальная(using или Dispose()).
А вот если часть данных объектов выходит за рамки описанного тобой класса, то задача становиться не совсем тривиальной.
Мы выделили ряд случаев:
Случай 1) Объект создает для своей работы SPSite и/или SPWeb но когда их уничтожать не знает, так как сам используется из вне.
Пример:
Класс А берет данные из узла и списка заданных в его конструкторе(передаются IDшники).
В данных списка храниться какая то структура.
Функция A.b(rootID) возвращает часть данной структуры - функция отрабатывает быстро, к ней сотни обращений за один цикл страницы.
Понятно, что для каждого вызова функции b, создавать новые объекты SPWeb и SPSite накладно. А когда уничтожить данные объект не известно
Наше решение: все подобные классы обязательно должны поддерживать интерфейс IDispouse, и подлежат обязательному уничтожению. В базе знаний компании создается список подобных объектов.
Случай 2) Статическая функция должна возвратить часть объекта SPWeb или SPSite. И для сохранения возвращаемой части, не может уничтожить объекты SPWeb и\или SPSite.
Пример:
public class MyUtilities
{
public static SPList GetList(string siteUrl, string webUrl, Guid id)
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb(webUrl))
{
SPList list = web.Lists[id];
//понятно что логика получения данных объектов может быть до безобразия сложной.
return list;
}
}
}
}
Понятно что в данном примере конструкция using абсолютно бесполезна. и объекты SPWeb и SPSite не будут уничтожены.
Решение: Написали класс (MyUsing) который отслеживает экземпляры объектов SPSite и SPWeb и уничтожает их. Условились, что в подобных ситуациях необходимо возвращать MyUsing.
Пример:
public class MyUtilities
{
public static MyUsing GetList(string siteUrl, string webUrl, Guid id)
{
SPSite site = new SPSite(siteUrl);
SPWeb web = site.OpenWeb(webUrl);
SPList list = web.Lists[id];
MyUsing result = new MyUsing();
result.Core = list;
result.Garbage.Add(web);
result.Garbage.Add(site);
return result;
}
}
Пример использования:
using(MyUsing myUsing = MyUtilities.GetList(...))
{
SPList list = (SPList)myUsing.Core;
string s = list.Title;
...
}
Случай 3) Объекты описные выше используются не нами. Тогда управлять их жизненным циклом мы вообще не можем. Существует ли события к которым можно подвязаться (Например уничтожения объекта контекста службами шарика), чтобы создать
статический сборщик мусора и чтоб при уничтожении контекста, он предварительно уничтожал данные объекты.
Народ, кто пытался комплексно решить данную проблему, поделитесь опытом? А может есть уже стандартное решения подобных проблем, и я просто о них не чего не знаю :(
На сайте MSDN нашел только рекомендации по уничтожению данных объектов только в очень тривиальной задаче(все в одной функции).
За ранее спасибо за комментарии :)