Warum sind für die LongRunning-Task (TPL) mit JpegBitmapDecoder keine Ressourcen mehr verfügbar?

Wir haben eine verwaltete .Net / C # -Anwendung, die TPL-Tasks erstellt, um die JPEG-Metadatencodierung für JPEG-Bilder durchzuführen. Jede Aufgabe wird mit der TaskCreationOptions.LongRunning-Option erstellt, z.

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

TaskProc () verwendet die Klassen JpegBitmapDecoder und JpegBitmapEncoder, um JPEG-Metadaten hinzuzufügen und neue Bilder auf der Festplatte zu speichern. Wir lassen zu, dass bis zu zwei solcher Aufgaben gleichzeitig aktiv sind, und dieser Vorgang sollte auf unbestimmte Zeit fortgesetzt werden.

Nach einiger Zeit der Durchführung der oben genannten bekommen wirEs ist nicht genügend Speicher verfügbar, um diesen Befehl zu verarbeiten Ausnahme beim Versuch, eine Instanz der JpegBitmapDecoder-Klasse zu erstellen:

System.ComponentModel.Win32Exception (0x80004005): Es ist nicht genügend Speicher verfügbar, um diesen Befehl unter MS.Win32.UnsafeNativeMethods.RegisterClassEx (WNDCLASSEX_D wc_d) zu verarbeiten.
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 () bei System.Windows.Threading.Dispatcher.get_CurrentDispatcher () bei System.Windows.Media.Imaging.BitmapDecoder..ctor (BitmapStream streamen, BitmapC reateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId) bei System.Windows .Media.Imaging.JpegBitmapDecoder..ctor (Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption)

Der Fehler ist aufgetretennur als wir JpegBitmapDecoder verwendet haben, um Metadaten hinzuzufügen. Mit anderen Worten, wenn die Aufgabe nur ein Bitmap-Bild in eine Datei kodieren und speichern würde, traten keine Probleme auf. Bei Verwendung von Process Explorer, Process Monitor oder anderen Diagnosetools wurde nichts Offensichtliches festgestellt. Es wurden überhaupt keine Gewinde-, Speicher- oder Grifflecks beobachtet. Wenn ein solcher Fehler auftritt, können keine neuen Anwendungen gestartet werden, z. B. Notizblock, Wort usw. Sobald unsere Anwendung beendet ist, kehrt alles zum Normalzustand zurück.

Die Taskerstellungsoption von LongRunning ist in MSDN als definiertGibt an, dass eine Aufgabe eine lang andauernde, grobkörnige Operation ist. Es gibt dem TaskScheduler einen Hinweis darauf, dass eine Überzeichnung gerechtfertigt sein kann. Dies impliziert, dass der zum Ausführen der Aufgabe ausgewählte Thread möglicherweise nicht aus dem ThreadPool stammt, d. H., Er wird für den Zweck der Aufgabe erstellt. Die anderen Optionen zum Erstellen von Aufgaben führen dazu, dass ein ThreadPool-Thread für die Aufgabe ausgewählt wird.

Nach einiger Zeit des Analysierens und Testens haben wir die Option zum Erstellen von Aufgaben auf etwas anderes als geändertLongRunning, z.B.,PreferFairness. Es wurden überhaupt keine weiteren Änderungen am Code vorgenommen. Dies "löste" das Problem, d.h. es gingen keine Speicherfehler mehr aus.

Wir sind uns nicht sicher, warum LongRunning-Threads die Schuldigen sind. Hier sind einige unserer Fragen dazu:

Warum sollte die Tatsache, dass die zur Ausführung der Aufgabe ausgewählten Threads aus dem ThreadPool stammen oder nicht? Wenn der Thread beendet wird, sollten seine Ressourcen nicht im Laufe der Zeit von GC zurückgefordert und unabhängig von seiner Herkunft an das Betriebssystem zurückgegeben werden?

Was ist das Besondere an der Kombination einer LongRunning-Aufgabe und der Funktionalität von JpegBitmapDecoder, die den Fehler verursacht?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage