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

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

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

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

Через некоторое время выполнения вышеупомянутого мы получаемNot enough storage is available to process this command исключение при попытке создать экземпляр класса JpegBitmapDecoder:

System.ComponentModel.Win32Exception (0x80004005): Not enough storage is available to process this command at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int3 2 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHoo k[] hooks) at System.Windows.Threading.Dispatcher..ctor() at System.Windows.Threading.Dispatcher.get_CurrentDispatcher() at System.Windows.Media.Imaging.BitmapDecoder..ctor(Stream bitmapStream, BitmapC reateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId) at System.Windows.Media.Imaging.JpegBitmapDecoder..ctor(Stream bitmapStream, Bit mapCreateOptions createOptions, BitmapCacheOption cacheOption)

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

Параметр создания задачи LongRunning определен в MSDN какSpecifies that a task will be a long-running, coarse-grained operation. It provides a hint to the TaskScheduler that oversubscription may be warranted. Это подразумевает, что поток, выбранный для запуска задачи, может быть не из ThreadPool, то есть он будет создан для цели задачи. Другие параметры создания задачи приведут к тому, что поток ThreadPool будет выбран для задачи.

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

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

Why should the fact that the threads chosen to execute the task come from the ThreadPool or not? If the thread terminates, shouldn't its resources be reclaimed over time by GC and returned back to the OS, regardless of its origin?

What is so special about the combination of a LongRunning task and JpegBitmapDecoder's functionality that causes the error?

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

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