Информирование ThreadPool.QueueUserWorkItem о требованиях к памяти - PullRequest
1 голос
/ 27 января 2012

Мы разрабатываем приложение, в котором пользователи могут ставить несколько задач одновременно.Мы используем ThreadPool.QueueUserWorkItem, чтобы установить выполнение задач.Эта часть работает хорошо.

У нас есть проблема, когда эти задачи могут потреблять более 500 МБ памяти.Мы используем отображенный в памяти ввод / вывод для управления памятью.Тем не менее, когда пользователи устанавливают более 10 задач, выполняющихся одновременно, пул потоков запускает их все, и были времена, когда у нас не хватало памяти, и возникали исключения.Мы можем справиться с ошибками очень хорошо.

Что мне интересно, так это то, есть ли способ учесть память, которая будет использоваться при обработке очереди, то есть сохранять задачи в очереди, пока не будет достаточно памяти?Могу ли я сообщить пулу потоков о том, сколько памяти мы будем запрашивать (что мы можем приблизительно оценить)?

Ответы [ 3 ]

0 голосов
/ 27 января 2012

ОК, если вы можете получить оценку памяти для каждой задачи, вы, вероятно, могли бы сделать это, сохранив приблизительный подсчет использования памяти в пуле с CS-защитой. Добавьте к этому счетчику непосредственно перед отправкой задачи, и пусть она вызовет функцию memRelease, чтобы вычесть из нее незадолго до ее завершения и проверить, можно ли что-либо выполнить сейчас (см. Позже).

Если какой-то поток хочет отправить задачу, и он обнаруживает (сравнивая свои потребности с текущим использованием в CS), что в «бюджете» недостаточно памяти для ее выполнения, вы можете засунуть ее в параллельная очередь / список, чтобы ждать, пока есть. Всякий раз, когда задача завершается и вызывает «memRelease», она добавляет в буфер памяти и выполняет итерацию очереди / списка (сначала блокируя его), чтобы попытаться найти что-то, что теперь можно запустить с увеличенной доступной памятью. Если это так, он отправляет задачу в пул.

0 голосов
/ 27 января 2012

Вы можете контролировать количество потоков в пуле потоков с помощью ThreadPool.SetMaxThreads.Итак, вы можете установить максимальное количество потоков

ThreadPool.SetMaxThreads = new PerformanceCounter("Memory", "Available MBytes").RawValue / 500;

PerformanceCounter («Память», «Доступные мегабайты»). RawValue -> Возвращает доступную память в МБ

0 голосов
/ 27 января 2012

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

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

...