Распределение spweb и spsite на sharepoint - PullRequest
2 голосов
/ 21 мая 2010

Я использую следующий код в среде .NET 1.1 SharePoint 2003, и он прекрасно работает:

            try
            {
                site = SPControl.GetContextSite(Context);
                web = site.OpenWeb();
                ...
            }
            catch (Exception export)
            {
                output.Write("Caught Exception: <br/><br/>");
                output.Write(export.Message + "<br><br>");
                output.Write(export.StackTrace);
            }
            finally
            {
                if (web != null)
                    web.Dispose();
                if (site != null)
                    site.Dispose();
            }

Однако в настоящее время я переносю код в среду .NET 2.0 SharePoint 2007 и получаю следующее сообщение об ошибке:

"Попытка использовать объект SPWeb, который был закрыт или удален и больше не действителен."

Если я закомментирую код Dispose (), он будет работать нормально. Но не вызовет ли это утечки памяти? Какой лучший способ решить проблему?

Ответы [ 4 ]

2 голосов
/ 21 мая 2010

Когда вы получаете объект SPSite от GetContextSite, вы получаете объект, который используется совместно со всем, что выполняется на этой странице.

После того, как вы утилизируете его, другой код пытается его использовать - отсюда и ошибка.

Вы должны распоряжаться только теми объектами, которые вы создали сами, а не теми, которые вы получаете с GetContextSite.

Быстрое решение (как говорит Iambriansreed) состоит в том, чтобы удалить блок finally и заменить первые две строки на.

SPSite site = SPContext.Current.Site; // Do you even need this?
SPweb web = SPContext.Current.Web;

Повышение производительности и отсутствие утечек памяти, поскольку среда SharePoint обрабатывает как создание, так и удаление объектов, извлеченных с помощью SPContext.

Однако - это сложный и плохо изученный предмет, поэтому необходимо внимательно прочитать Рекомендации: использование одноразовых объектов Windows SharePoint Services и использование SPDisposeCheck tool . *

1 голос
/ 21 мая 2010

При работе с одноразовыми объектами, в частности с SharePoint, проще использовать using:

using(SPSite site = new SPSite("..."))
using(SPWeb web = site.OpenWeb("..."))
{

}

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

См. Также - Использование одноразовых объектов Windows SharePoint Services :

Объекты SPContext управляются средой SharePoint и не должны явно размещаться в вашем коде. Это также верно для объектов SPSite и SPWeb, возвращаемых SPContext.Site, SPContext.Current.Site, SPContext.Web и SPContext.Current.Web.

1 голос
/ 21 мая 2010

Также лучший способ сделать выше:

site = SPControl.GetContextSite(Context);
web = site.OpenWeb()

является следующим:

SPSite site = SPContext.Current.Site;
SPweb web = SPContext.Current.Web;

Здесь нет утечек памяти. Если серьезно; собирается в 2007 году, а не в 2010 году?

0 голосов
/ 21 мая 2010

Поместите ваш код в операторы, которые автоматически вызовут dispose, когда объекты выйдут из области видимости.

using(site = SPControl.GetContextSite(Context))
{
    using(web = site.OpenWeb())
    {
    //your code
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...