Например, в ниже кода 'image'object будет создан и затем собрал "мусор" в некоторой неизвестной точке в будущем
void MyFunction() {
Bitmap image = RetrieveImage();
DoSomething(image);
}
Что относительно
void MyFunction() {
DoSomething(RetrieveImage());
}
В этом случае объект, собравший "мусор", после того как он перемещается из объема т.е. После конца MyFunction. Если не существует ли где-нибудь для осуществления этого?
Нет. На самом деле, вы не хотите, чтобы мусор собирался - частое обращение к сборщику мусора снизит производительность.
То, что вы хотите сделать , это утилизировать неуправляемые ресурсы вовремя - и вот тут появляется IDisposable
, вместе с , используя
утверждение:
void MyFunction()
{
using (Bitmap image = RetrieveImage())
{
DoSomething(image);
}
}
Это вызовет образ. Диспозиция()
по мере выхода из оператора с использованием
, независимо от того, бросило ли DoSomething
исключение или нет. Однако
Вы должны использовать дополнительную переменную - если только вы не измените DoSomething
, чтобы взять вместо него Func
, так что вместо:
void DoSomething(Bitmap image)
{
// Code here
}
...
DoSomething(RetrieveImage());
вы должны:
void DoSomething(Func<Bitmap> imageProvider)
{
using (Bitmap image = imageProvider())
{
// Code here
}
}
...
DoSomething(() => RetrieveImage());
Обратите внимание, что это не дает возможности передать битовую карту без ее расположения - что может быть проблемой, если вы захотите использовать ее снова позже. Тем не менее, это хорошая техника, о которой, по крайней мере, нужно знать.
EDIT: Как отметил Мбекиш в своих комментариях, здесь не так уж и много пользы от простого распоряжения растровой картой в пределах RetrieveImage
. Но вот вариант с паттерном:
public void ApplyToEachLineInFile(string file, Action<string> action)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
action(line);
}
}
}
Здесь логика "приобретай и распоряжайся" инкапсулирована, и звонящий об этом не беспокоится - но при этом он может быть очень гибким в плане сложности логики, в которую он входит.
Коллекция мусора не происходит, когда объект выпадает из объема. Скорее это автоматическая функция управления памятью из рамки.
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
Вы можете заставить .NET собирать мусор, но если вы не испытываете серьезные проблемы памяти, я бы не рекомендовал вам идти вниз по этому пути.
Вы можете обеспечить соблюдение сборки мусора с:
после того, как он правильно утилизируется (см. Джонс ответ на использование () {} - синтаксис ).
Не забывайте (как я только что сделал)
system.gc.waitforpendingfinalizers ();
после этого.
edit>
Хотя он не рекомендуется - как сказал Джон.
Примечание : Вы не хотите этого делать. Коллектор мусора .NET - «умнее», чем вы (или я, или Джон-Скелет или кто-либо еще).
try
{
Bitmap image = RetrieveImage();
DoSomething(image);
}
finally
{
GC.Collect();
}
(Это предполагает, что ни один из объектов, которые не выпадают в реализации масштаба, реализуемыми IDSposable)