Действительно ли возможно записать C# так, чтобы объекты были собраны "мусор", когда они падают из объема?

Например, в ниже кода 'image'object будет создан и затем собрал "мусор" в некоторой неизвестной точке в будущем

void MyFunction() {

    Bitmap image = RetrieveImage();
    DoSomething(image);
}

Что относительно

void MyFunction() {

    DoSomething(RetrieveImage());

}

В этом случае объект, собравший "мусор", после того как он перемещается из объема т.е. После конца MyFunction. Если не существует ли где-нибудь для осуществления этого?

6
задан deltanovember 27 January 2010 в 21:00
поделиться

4 ответа

Нет. На самом деле, вы не хотите, чтобы мусор собирался - частое обращение к сборщику мусора снизит производительность.

То, что вы хотите сделать , это утилизировать неуправляемые ресурсы вовремя - и вот тут появляется 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);
        }
    }
}

Здесь логика "приобретай и распоряжайся" инкапсулирована, и звонящий об этом не беспокоится - но при этом он может быть очень гибким в плане сложности логики, в которую он входит.

19
ответ дан 8 December 2019 в 04:08
поделиться

Коллекция мусора не происходит, когда объект выпадает из объема. Скорее это автоматическая функция управления памятью из рамки.

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

Вы можете заставить .NET собирать мусор, но если вы не испытываете серьезные проблемы памяти, я бы не рекомендовал вам идти вниз по этому пути.

4
ответ дан 8 December 2019 в 04:08
поделиться

Вы можете обеспечить соблюдение сборки мусора с:

System.gc.coCollect ()

после того, как он правильно утилизируется (см. Джонс ответ на использование () {} - синтаксис ).

Не забывайте (как я только что сделал)

system.gc.waitforpendingfinalizers ();

после этого.

Хотя он не рекомендуется - как сказал Джон.

0
ответ дан 8 December 2019 в 04:08
поделиться

Примечание : Вы не хотите этого делать. Коллектор мусора .NET - «умнее», чем вы (или я, или Джон-Скелет или кто-либо еще).

try
{
    Bitmap image = RetrieveImage();
    DoSomething(image);
}
finally
{
    GC.Collect();
}

(Это предполагает, что ни один из объектов, которые не выпадают в реализации масштаба, реализуемыми IDSposable)

3
ответ дан 8 December 2019 в 04:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: