2010-09-24 5 views
6

Jaki jest właściwy sposób usuwania obiektów utworzonych w funkcji? Natknąłem się na tę metodę na stronie internetowej.Jak bezpiecznie pozbyć się obiektów SharePoint w funkcjach PowerShell?

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

Czy metoda Dispose jest wywoływana w tej funkcji?

+0

Jeśli pochodzisz ze świata .NET - nie ma to jak "używanie". Ale domyślam się, że widziałem kilka poleceń funkcji na ms connect. – stej

Odpowiedz

9

Po pierwsze, w rzeczywistości nie chcesz wywoływania wywoływanego tutaj w każdym razie - gdy wywołasz Dispose na instancji SPSite, wszystkie sieci zwrócony za pośrednictwem OpenWeb są również usuwane, ponieważ są "własnością" tego SPSite!

Jednym z modeli używanych przez cmdlet programu SharePoint 2010 jest rodzaj "odroczonej dyspozycji", co oznacza, że ​​instancje SPWeb nie są usuwane, dopóki nie zakończą się prace nad potokiem, w którym są zaangażowane. Działa to tak:

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() 
    } 
} 

Teraz tutaj jest, jak to działa w praktyce (jest to jeden wiersz):

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

Pierwsza część uzyska jeden SPWeb instancji i przekazać je do ForEach-Object część. Dopiero po zakończeniu foreoura (i zakończeniu zmiany tytułu strony internetowej) zostanie wywołany odpowiedni blok końcowy w get-spweb, który udostępnia stronę i sieć. Ważne jest to, że cały potok jest pojedynczym blokiem kodu, który jest wykonywany w jednym wywołaniu.

Ten nie będzie praca interaktywnie tak:

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 

Więc w tym ostatnim przykładzie trzeba by użyć innego realizację Get-spweb (który omija blok końcowy lub zablokowanie to z parametrem przełączania), a następnie musisz sam się pozbyć.

Kolejnym ważnym szczegółem jest to, że praca interaktywna w grze Powerhell z obiektami Sharepoint spowoduje wyciek pamięci. Domyślnie powershell działa w MTA (multi-threaded apartment) i użyje puli wątków do wykonania poleceń. Każda wprowadzona linia będzie używać innego wątku. Za każdym razem, gdy uzyskujesz dostęp do obiektu COM z innym wątkiem, wyciekniesz trochę pamięci z niezarządzanego sterty, gdy nowa sterty zostanie przydzielona dla przełącznika kontekstu (bez uwolnienia starej). Można to złagodzić uruchamiając powershell.exe z przełącznik -STA. Zapewni to, że wszystkie polecenia i potoki zostaną wykonane przy użyciu tego samego wątku, co pozwoli uniknąć wycieku pamięci. To powiedziawszy, po prostu zamknięcie konsoli Power Shell odzyska całą tę pamięć ponownie, ale długo działające skrypty mogą głodować twoje serwery pamięci, jeśli nie będziesz ostrożny, niszcząc SharePoint (cokolwiek innego, co nie lubi być zagłodzonym z zestawu roboczego.) Dlatego też podejście jednoliniowe działa tak dobrze w poprzednim przykładzie: obiekt jest alokowany i umieszczany w tym samym rurociągu, a przez to w tym samym wątku. Bez wycieku.

+0

W jaki sposób pasuje to do 'Start-SPAssignment -Global' –

+0

@Lavinski Przy przypisaniu start/stop instancje nie są usuwane na końcu przebiegu potoku. Zostają unieszkodliwieni, gdy wezwiesz stop. – x0n

7

Nie, nie dlatego, że powracasz do funkcji najpierw przed wywołaniem Dispose. Jeśli masz zasobów, które muszą być usuwane następnie chciałbym użyć try/finally tak:

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

Zaletą wreszcie jest to, że utylizować będzie sprawdzony bez względu na sposób wyjścia z bloku try (albo pomyślnie, z powodu błędu lub z powodu instrukcji return).

Powiązane problemy