2011-07-08 27 views
12

Tengo un método personalizado que encuentra el tamaño más grande para usar para una cadena y fuente dada para llenar un cuadro dado sin cortar el texto. Para probarlo, creé un servicio que realiza ciclos a través de algunas cadenas diferentes y unas pocas fuentes diferentes y hace lotes de ellas en un bucle Parallel.For. Cuando se está ejecutando este servicio, todos los núcleos de la CPU en un sistema están en% 90-% 100. Después de correr durante 8 o 9 horas, comenzará a lanzar excepciones. Todavía funcionará la mayor parte del tiempo, pero habrá excepciones ocasionales o ráfagas de excepciones."La operación se completó correctamente" excepción

La excepción más interna tiene el mensaje "La operación se completó correctamente" y se origina en el acceso WidthIncludingTrailingWhitespace en un objeto FormattedText. La pila de llamadas es el siguiente:

at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d) 
    at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks) 
    at System.Windows.Threading.Dispatcher..ctor() 
    at System.Windows.Threading.Dispatcher.get_CurrentDispatcher() 
    at System.Windows.Media.TextFormatting.TextFormatter.FromCurrentDispatcher(TextFormattingMode textFormattingMode) 
    at System.Windows.Media.FormattedText.LineEnumerator..ctor(FormattedText text) 
    at System.Windows.Media.FormattedText.DrawAndCalculateMetrics(DrawingContext dc, Point drawingOffset, Boolean getBlackBoxMetrics) 
    at System.Windows.Media.FormattedText.get_Metrics() 
    at System.Windows.Media.FormattedText.get_WidthIncludingTrailingWhitespace() 
    ...My Library Here... 

En la investigación de este, he encontrado que los objetos de dibujo no vendida (gráficos, iconos, etc) son una causa común para esto, pero no pude encontrar ningún objeto desechables de uso. El código de tamaño de texto utiliza clases WPF (FontFamily, FormattedText y Typeface) y ninguno de ellos implementa IDisposable.

Tengo un monitoreo perfmon del proceso y, aunque el uso de memoria, el conteo de identidades y el número de subprocesos varían bastante, nunca se disparan fuera de control. Esto me dice que probablemente no es una fuga de controlador. ¿Qué más podría ser?

ACTUALIZACIÓN: He estado ejecutando la prueba durante unos días con un cambio significativo: está haciendo un regular en lugar de un paralelo para. Todavía no se ha bloqueado y perfmon muestra líneas horizontales con muy poca variación. Tal vez este es un problema con la paralelización y no la representación de texto WPF?

Respuesta

0

Parece que se produjo una excepción cuando WPF intentó asignar el identificador nativo de la ventana Win32 para otro nuevo Dispatcher. ¿Tal vez ha alcanzado la cantidad máxima de identificadores para su proceso?

¿Intentó forzar la recolección de basura en cada iteración? La mayoría de las clases WPF no implementa IDisposable, pero aún usan recursos no administrados, que se administran dentro de WPF.

Hay otra forma de desbordamiento que puedo imaginar. La propiedad CurrentDispatcher crea un nuevo Dispatcher para cada hilo. Cada despachador nunca se detiene hasta que se llame a InvokeShutdown. Por lo tanto, significa que un subproceso en el que funciona un Dispatcher nunca terminará, porque no hay ventana y no hay nadie para presionar el botón Cerrar. Quizás fuerza Paralelo. Para la implementación, asigne un nuevo subproceso para la próxima iteración, que también necesita otro nuevo despachador y otro nuevo. Lamentablemente, no tengo mucha experiencia en el uso de Parallel, así que esto es solo suposición.

+0

Tengo perfmon ejecutándose en el proceso y el uso del asa rebota mucho, no tiene una tendencia ascendente, así que no creo que ese sea el problema. Intenté forzar la recogida de basura periódicamente, no sirvió de nada. Esa última sugerencia es interesante. Perfmon no muestra ninguna tendencia al alza con los hilos, pero este es un buen lead como cualquier otro. ¡Gracias! –

Cuestiones relacionadas