2010-09-24 18 views
6

Cách xử lý đúng đối tượng được tạo ra bên trong một hàm là gì? Tôi đã xem qua phương pháp này trên một trang web.Làm thế nào tôi có thể vứt bỏ các đối tượng SharePoint một cách an toàn trong các chức năng PowerShell?

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

Phương thức Dispose có được gọi trong chức năng này không?

+0

Nếu bạn đến từ thế giới .NET - không có gì giống như 'using'. Nhưng tôi đoán tôi thấy một số yêu cầu tính năng trên ms kết nối. – stej

Trả lời

9

Đầu tiên, bạn không thực sự muốn Vứt bỏ được gọi ở đây - khi bạn gọi Vứt bỏ trên một trường hợp SPSite, tất cả các web được trả về thông qua OpenWeb cũng được xử lý bởi vì chúng được "sở hữu" bởi SPSite đó!

Một trong các mô hình được sử dụng bởi lệnh ghép ngắn SharePoint 2010 là một loại "xử lý hoãn lại" có nghĩa là các cá thể SPWeb không được xử lý cho đến khi đường dẫn mà chúng tham gia hoàn thành. Này hoạt động như thế này:

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

Bây giờ ở đây là cách làm việc này trong thực tế (đây là một dòng duy nhất):

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

Phần đầu tiên sẽ có được một SPWeb trường hợp duy nhất và vượt qua nó để ForEach-Object phần. Chỉ khi foreach hoàn thành (và kết thúc việc thay đổi tiêu đề của trang web) thì khối End tương ứng sẽ được gọi trong số get-spweb, để phân phối trang web và web. Điều quan trọng là toàn bộ đường ống là một khối mã duy nhất được thực hiện trong một cuộc gọi duy nhất.

này sẽ không việc tương tác như thế này:

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 

Vì vậy, trong ví dụ sau này bạn sẽ phải sử dụng một thực hiện khác nhau của get-SPWeb (một mà bỏ qua khối kết thúc, hoặc ngăn chặn nó với một tham số chuyển đổi) và sau đó bạn sẽ phải vứt bỏ trang web cho mình.

Một chi tiết quan trọng khác là làm việc tương tác trong powerhell với các đối tượng sharepoint sẽ khiến bạn bị rò rỉ bộ nhớ. Theo mặc định, PowerShell chạy trong MTA (căn hộ nhiều luồng) và sẽ sử dụng một nhóm các chủ đề để thực thi các lệnh của bạn. Mỗi dòng được nhập sẽ sử dụng một chuỗi khác nhau. Mỗi khi bạn truy cập một đối tượng COM với một luồng khác, bạn sẽ rò rỉ một số bộ nhớ từ vùng không được quản lý như một vùng heap mới được cấp phát cho chuyển đổi ngữ cảnh (không có phần cũ được giải phóng.) Điều này có thể được giảm bớt bằng cách khởi động PowerShell.exe với công tắc -STA. Điều này sẽ đảm bảo rằng tất cả các lệnh và đường ống được thực hiện với cùng một luồng, tránh rò rỉ bộ nhớ. Điều đó nói rằng, chỉ cần đóng console powershell sẽ lấy lại tất cả bộ nhớ đó một lần nữa nhưng các script chạy dài có thể làm đói máy chủ của bạn nếu bạn không cẩn thận, đưa xuống SharePoint (bất kỳ thứ gì khác không muốn bị bỏ đói bộ làm việc.) Đây là lý do tại sao phương pháp tiếp cận một dòng hoạt động rất tốt trong ví dụ trước đây: đối tượng được phân bổ và xử lý trong cùng một đường ống, và bằng phần mở rộng, cùng một luồng. Không bị rò rỉ.

+0

Làm thế nào để điều này phù hợp với 'Bắt đầu-SPAssignment -Global' –

+0

@Lavinski Với nhiệm vụ bắt đầu/dừng, sau đó các trường hợp không được xử lý ở cuối đường ống. Họ bị xử lý khi bạn gọi dừng lại. – x0n

7

Không phải vì bạn không trả lại chức năng trước trước khi gọi Dispose. Nếu bạn có nguồn lực mà phải được xử lý sau đó tôi sẽ sử dụng một thử/cuối cùng tuyên bố như vậy:

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

Những điều tốt đẹp về cuối cùng là dispose sẽ được gọi là không có vấn đề làm thế nào bạn thoát khỏi khối try (hoặc thành công, vì lỗi hoặc vì báo cáo trả lại).

Các vấn đề liên quan