Почему у задачи LongRunning (TPL) с JpegBitmapDecoder заканчиваются ресурсы?

У нас есть управляемое приложение .Net / C #, которое создает задачи TPL для выполнения кодирования метаданных JPEG на изображениях JPEG. Каждая задача создается с параметром TaskCreationOptions.LongRunning, например,

Task task = new Task( () => TaskProc(), cancelToken, TaskCreationOptions.LongRunning );

TaskProc () использует классы JpegBitmapDecoder и JpegBitmapEncoder для добавления метаданных JPEG и сохранения новых изображений на диск. Мы разрешаем одновременно активировать до 2 таких задач, и этот процесс должен продолжаться бесконечно.

Через некоторое время выполнения вышеупомянутого мы получаемНедостаточно памяти для обработки этой команды исключение при попытке создать экземпляр класса JpegBitmapDecoder:

System.ComponentModel.Win32Exception (0x80004005): недостаточно места для обработки этой команды в MS.Win32.UnsafeNativeMethods.RegisterClassEx (WNDCLASSEX_D wc_d)

в MS.Win32.HwndWrapper..ctor (Int32 classStyle, стиль Int32, Int32 exStyle, Int3 2 x, Int32 y, ширина Int32, высота Int32, имя строки, родительский IntPtr, хуки HwndWrapperHoo k []) в System.Windows.Threading .Dispatcher..ctor () в System.Windows.Threading.Dispatcher.get_CurrentDispatcher () в System.Windows.Media.Imaging.BitmapDecoder..ctor (Поток bitmapStream, BitmapC reateOptions createOptions, BitmapCacheOption cacheOption, Guid Ожидаемый ClsId) в System.Windows .Media.Imaging.JpegBitmapDecoder..ctor (Поток bitmapStream, Bit mapCreateOptions createOptions, BitmapCacheOption cacheOption)

Произошла ошибкатолько когда мы использовали JpegBitmapDecoder для добавления метаданных. Другими словами, если задача просто закодирует & сохранить растровое изображение в файл, проблем не возникло. Ничего очевидного не было обнаружено при использовании Process Explorer, Process Monitor или других средств диагностики. Никаких утечек потока, памяти или ручки не наблюдалось вообще. Когда возникает такая ошибка, никакие новые приложения не могут быть запущены, например, блокнот, слово и т. Д. Как только наше приложение завершается, все возвращается в нормальное состояние.

Параметр создания задачи LongRunning определен в MSDN какУказывает, что задача будет длительной, крупнозернистой операцией. Он дает подсказку TaskScheduler, что переподписка может быть оправдана. Это подразумевает, что поток, выбранный для запуска задачи, может быть не из ThreadPool, то есть он будет создан для цели задачи. Другие параметры создания задачи приведут к тому, что поток ThreadPool будет выбран для задачи.

После некоторого времени анализа и тестирования мы изменили параметр создания задачи на любой другой, кромеLongRunningнапример,PreferFairness, Других изменений в коде не было. Это "решены» проблема, то есть, больше нет исчерпания ошибок хранения.

Мы озадачены фактической причиной того, что нити LongRunning являются виновниками. Вот некоторые из наших вопросов по этому вопросу:

Почему тот факт, что потоки, выбранные для выполнения задачи, происходят из ThreadPool или нет? Если поток завершается, не долженмогут ли его ресурсы быть восстановлены со временем GC и возвращены обратно в ОС, независимо от ее происхождения?

Что особенного в комбинации задачи LongRunning и JpegBitmapDecoder 'С функциональностью, которая вызывает ошибку?

Ответы на вопрос(2)

Ваш ответ на вопрос