Por que a tarefa LongRunning (TPL) com o JpegBitmapDecoder fica sem recursos?

Temos um aplicativo .Net / C # gerenciado que cria tarefas TPL para executar a codificação de metadados JPEG em imagens JPEG. Cada tarefa é construída com a opção TaskCreationOptions.LongRunning, por exemplo,

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

TaskProc () utiliza classes JpegBitmapDecoder e JpegBitmapEncoder para adicionar metadados JPEG e salvar novas imagens em disco. Permitimos que até 2 dessas tarefas estejam ativas a qualquer momento, e esse processo deve continuar indefinidamente.

Depois de algum tempo de realizar o supracitado, recebemosNão está disponível armazenamento suficiente para processar este comando exceção ao tentar criar uma instância da classe JpegBitmapDecoder:

System.ComponentModel.Win32Exception (0 x 80004005): armazenamento insuficiente está disponível para processar este comando em MS.Win32.UnsafeNativeMethods.RegisterClassEx (WNDCLASSEX_D wc_d)
em MS.Win32.HwndWrapper..ctor (Int32 classStyle, Int32 estilo, Int32 exStyle, Int3 2 x, Int32 y, largura Int32, Int32 height, nome de seqüência de caracteres, pai IntPtr, HwndWrapperHoo k [] ganchos) em System.Windows.Threading .Dispatcher..ctor () em System.Windows.Threading.Dispatcher.get_CurrentDispatcher () em System.Windows.Media.Imaging.BitmapDecoder..ctor (Stream bitmapStream, bitmapC reateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId) em System.Windows .Media.Imaging.JpegBitmapDecoder..ctor (Stream bitmapStream, Bit mapCreateOptions createOptions, BitmapCacheOption cacheOption)

O erro ocorreusó quando utilizamos o JpegBitmapDecoder para adicionar metadados. Em outras palavras, se a tarefa apenas codificasse e salvasse uma imagem Bitmap no arquivo, não surgiram problemas. Nada óbvio foi revelado ao usar o Process Explorer, Process Monitor ou outras ferramentas de diagnóstico. Nenhum segmento, memória ou vazamentos de identificadores foram observados. Quando tal erro ocorre, nenhum novo aplicativo pode ser iniciado, por exemplo, bloco de notas, palavra, etc. Uma vez que nosso aplicativo é encerrado, tudo volta ao normal.

A opção de criação de tarefas de LongRunning é definida no MSDN comoEspecifica que uma tarefa será uma operação longa e de granulação grossa. Ele fornece uma dica para o TaskScheduler de que o excesso de inscrição pode ser garantido. Isto implica que o encadeamento escolhido para executar a tarefa pode não ser do ThreadPool, ou seja, será criado para o propósito da tarefa. As outras opções de criação de tarefa resultarão em um thread ThreadPool sendo selecionado para a tarefa.

Depois de algum tempo analisando e testando, mudamos a opção de criação de tarefas para outra coisa que nãoLongRunning, por exemplo.,PrefiroFairness. Nenhuma outra alteração no código foi feita. Isso "resolveu" o problema, ou seja, não há mais erros de armazenamento.

Estamos confusos quanto à razão real para os fios LongRunning serem os culpados. Aqui estão algumas das nossas perguntas sobre isso:

Por que o fato de os encadeamentos escolhidos para executar a tarefa virem do ThreadPool ou não? Se o encadeamento terminar, seus recursos não devem ser recuperados ao longo do tempo pelo GC e retornados ao sistema operacional, independentemente de sua origem?

O que há de tão especial na combinação de uma tarefa LongRunning e na funcionalidade do JpegBitmapDecoder que causa o erro?

questionAnswers(2)

yourAnswerToTheQuestion