Как безопасно утилизировать объекты SharePoint в функциях PowerShell? - PullRequest
6 голосов
/ 24 сентября 2010

Как правильно расположить объекты, созданные внутри функции? Я сталкивался с этим методом на веб-сайте.

function get-spweb ([String]$webUrl=$(throw 'Parameter -webUrl is missing!'))
{
   $site = get-SPSite $weburl
   return $site.OpenWeb()
   $site.Dispose()
}

Вызывается ли когда-либо метод Dispose в этой функции?

Ответы [ 3 ]

10 голосов
/ 26 сентября 2010

Во-первых, вы все равно на самом деле не хотите, чтобы Dispose вызывался здесь - когда вы вызываете Dispose для экземпляра SPSite, все веб-сайты, возвращаемые через его OpenWeb, также удаляются, поскольку они "принадлежат" этому SPSite!* Одна из моделей, используемых командлетами SharePoint 2010, является своего рода «отложенным удалением», которое означает, что экземпляры SPWeb не удаляются до завершения конвейера, в котором они участвуют.Это работает так:

function Get-SPWeb {
     param([uri]$Url)

     begin {
         # get SPSite that owns the passed Url
         $site = new-object microsoft.sharepoint.spsite $url
         # return specific SPWeb instance
         $site.OpenWeb() 
     }
     end {
         # this disposes owning spsite AND the returned web
         $site.Dispose()
     }
}

Теперь вот как это работает на практике (это одна строка):

ps> get-spweb "http://localhost/sites/test" | foreach-object {
    $_.Title = "New Name"; $_.update()
}

Первая часть получит один экземпляр SPWebи передать его в часть ForEach-Object.Только когда foreach завершит (и закончит изменение заголовка сети), соответствующий блок End будет вызываться в get-spweb, который удаляет сайт и сеть.Важно то, что весь конвейер представляет собой один блок кода, который выполняется за один вызов.

Этот не будет работать в интерактивном режиме так:

ps> $w = get-spweb "http://localhost/sites/test" # calls begin AND end
ps> $w.title = "new name"
ps> $w.update() # boom! web is already disposed

Таким образом, в этом последнем примере вам придется использовать другую реализацию get-spweb (ту, которая пропускает конечный блок или подавляет его с помощью параметра switch), а затем вам придется самостоятельно утилизировать сайт.

Еще одна важная деталь: интерактивная работа в powershell с объектами sharepoint приведет к утечке памяти. По умолчанию powershell работает в MTA (многопоточная квартира) и будет использовать пулпотоки для выполнения ваших команд.Каждая введенная строка будет использовать другую ветку.Каждый раз, когда вы обращаетесь к COM-объекту с другим потоком, вы теряете часть памяти из неуправляемой кучи, так как новая куча выделяется для переключения контекста (без освобождения старой). Это можно облегчить, запустив powershell.exe спереключатель -STA.Это обеспечит выполнение всех команд и конвейеров в одном потоке, что позволит избежать утечки памяти.Тем не менее, простое закрытие консоли powershell восстановит всю эту память снова, но долго выполняющиеся сценарии могут лишить ваши серверы памяти памяти, если вы не будете осторожны, что приведет к отключению SharePoint (чего-либо еще, что не хочет лишиться рабочего набора.) Вот почему однострочный подход так хорошо работает в первом примере: объект размещается и размещается в одном и том же конвейере и, соответственно, в одном и том же потоке.Нет утечки.

7 голосов
/ 24 сентября 2010

Нет, это не потому, что вы сначала выходите из функции перед вызовом Dispose.Если у вас есть ресурсы, которые нужно утилизировать, я бы использовал инструкцию try / finally, например, так:

$site = Get-SPSite $weburl
try {
 # do stuff to $site until done with it
}
finally {
    $site.Dispose()
}

Хорошая вещь в заключении заключается в том, что утилита dispose будет вызываться независимо от того, как вы выйдете из блока try.(либо успешно, либо из-за ошибки, либо из-за оператора возврата).

0 голосов
/ 20 июля 2014

лучшим логическим эквивалентом будет использование «Start-SPAssignment».подробней http://technet.microsoft.com/en-us/library/ff607664(v=office.15).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...