Урожай и освобождение памяти - PullRequest
2 голосов
/ 23 октября 2010

У меня есть веб-сервис WCF, который я использую для отправки изображений из моего клиентского приложения Windows Mobile на мой сервер.

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

Что я хочу знать, так это то, что если я настрою IEnumerable и yield изображений из базы данных по 1 за раз, будет ли освобождена память после каждой отправки пакета?

Я знаю, что полагаться на сборщик мусора для быстрой очистки, как правило, плохая идея. Поэтому я не решаюсь сделать это (и, следовательно, причина, по которой я спрашиваю).

Единственный другой вариант, который я вижу, - это вызвать базу данных, чтобы получить данные в наборах по 10 (кажется, не элегантно, но мне, возможно, придется это сделать).

Позвольте мне подвести итог с примером. Скажем, у меня есть следующий код. Когда элемент, возвращаемый yield (MyYieldingEnumerable), освободит память (или, по крайней мере, будет доступен для сборки мусора)?

public void SendImages()
{
    List<ImageItem> itemsToSend = new List<ImageItem>();
    int count = 0;
    foreach (ImageItem curImageItem in MyYieldingEnumerable())
    {
        itemsToSend.Add(curImageItem);
        count++;
        if (count >= 10)
        {
            myService.SendItems(itemsToSend);

            // #1 When the last reference to it is removed
            //     |
            //     v
            itemsToSend = new List<ImageItem>();
            count = 0;
        }
    }
    // <----- #2 After the loop ends
}
// <------- #3 After the method exits

Будут ли они в памяти по 10 партий или все они останутся в памяти одновременно?

1 Ответ

4 голосов
/ 23 октября 2010

Это зависит от того, что ваш код делает в MyYieldingEnumerable и как создается список boxes.Список itemsToSend, если он не поддерживается с помощью вызова myService.SendItems, не будет ссылаться, и, следовательно, GC может восстановить его.Но слишком много кода не хватает, чтобы вынести вердикт.

Но настоящая проблема не в этом коде, а в вашем общем подходе к обработке передачи файлов.Загрузка всего файла (ов) в память и передача их прокси WCF просто не будет работать в реальной жизни.Один только один файл может быть достаточно большим, чтобы испортить ваше приложение, поэтому пакетирование 10 ничего не экономит.Вам необходимо реализовать чистую потоковую семантику, сквозную: от чтения файла на клиенте в чанах, отправки его в чанах и записи в месте назначения в чанках.Если эти операции передачи файлов являются основной задачей приложения, тогда возобновление (возможность возобновления передачи файла с определенного смещения) и, возможно, справедливость (один большой файл не прерывает все остальные файлы), вероятно, также являются требованиями.

Предлагаю перейти к этой теме в MSDN: WCF Как: включить потоковую передачу .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...