2013-06-06 28 views
24

W języku C# class Process dziedziczy po class Component, który implementuje IDisposable, dzięki czemu można wywołać Dispose() na dowolnym obiekcie Process. Czy naprawdę muszę? Skąd mam wiedzieć, czy naprawdę muszę?Co właściwie robi funkcja Process.Dispose()?

Załóżmy, że mam następujący kod:

var allProcesses = System.Diagnostics.Process.GetProcesses(); 
var processesNames = processes.Select(p => p.ProcessName); 
// output process names here 

Teraz wygląda na to, mam tablicę Process obiektów i muszę spreparować try-finally przemierzać tablicy i Dispose() każdego obiektu. To z pewnością dużo dodatkowego kodu.

Co robi ta Dispose() dla obiektów Process? Czy naprawdę muszę do Dispose() co obiekt Process i jak zdecydować, czy muszę to zrobić?

+0

czas odbłyśnika? –

Odpowiedz

23

Czy naprawdę muszę Dispose() każdy Process przedmiot i jak mogę zdecydować, czy muszę to zrobić?

Tak, należy je wyrzucić. Zapamiętaj ten tekst w dokumentacji dla: Process:

Proces systemowy jest unikalnie identyfikowany w systemie przez jego identyfikator procesu. Podobnie jak wiele zasobów systemu Windows, proces jest również identyfikowany przez jego uchwyt, który może nie być unikalny na komputerze. Uchwyt jest ogólnym terminem określającym identyfikator zasobu. System operacyjny utrzymuje uchwyt procesu, do którego dostęp uzyskuje się za pomocą właściwości Handle komponentu Process, nawet gdy proces zakończył się. W ten sposób można uzyskać informacje administracyjne procesu, takie jak ExitCode (zwykle zero dla sukcesu lub niezerowy kod błędu) i ExitTime. Uchwyty są niezwykle cennym zasobem, więc przeciekające uchwyty są bardziej zjadliwe niż wycieki pamięci.

Więc jeśli nie Dispose je, jesteś potencjalnie przecieka uchwyty (dopóki są one zbierane śmieci - ale cały punkt Dispose jest umożliwienie wczesnego oczyszczanie zasobów)


Należy również zauważyć, że ta sama dokumentacja wskazuje, że Process przesłania Dispose(bool) - kolejną wskazówkę, że w rzeczywistości jest to coś podczas wywołania .

+1

Bardzo chciałbym użyć 'używając (IEnumerable ...)' tutaj :) – eFloh

+2

@eFloh - nie jestem pewien, co tam celujesz. Instrukcja "using" wprowadza nową zmienną i zakres, w którym ta zmienna będzie używana. Podczas gdy "używanie" może być używane tylko w przypadku obiektów jednorazowych, prawie zawsze należy korzystać z ich "jednorazowych" aspektów w tym zakresie. –

+0

Po prostu ładny syntaksonowy skracacz ... Specjalnie dla tych przypadków, w których masz całą listę materiałów jednorazowych, dobrze byłoby mieć składnię, by ostatecznie je usunąć bez potrzeby "finally {foreach (... x. ..) {x.Dispose(); }} ' – eFloh

1

z MSDN: http://msdn.microsoft.com/en-us/library/3cc9y48w(v=vs.80).aspx

połączeń utylizować po zakończeniu korzystania z komponent. Metoda usuwania pozostawia komponent w stanie niezdatnym do użytku. Po wywołaniu Dispose, musisz zwolnić wszystkie odniesienia do Component, aby garbage collect mógł odzyskać pamięć zajmowaną przez Komponent.