¿Valdrían la pena las actualizaciones de la interfaz de usuario por lotes contra el cuello de botella de BeginInvoke?

Estoy en una situación en la que tengo archivos de texto que representan un objeto de juego. Lo que tengo que hacer es analizar el archivo y obtener los puntos a los que se dibujará el objeto del juego. Por ejemplo

fruits.txt
pear 10, 20
orange 10,38

Cada vez que grep un punto, uso dispatcher begininvoke para actualizar la nueva fruta en la pantalla. Esto funciona mejor que invocar para un solo hilo. Siempre que tengo más de una pantalla actualizando sus puntos en paralelo se vuelve muy lento y se empieza a colgar o el marco salta mientras dibujo a la pantalla. ¿Esto se debe a que BeginInvoke pone en cola los mensajes? A pesar de la congelación, BeginInvoke todavía funciona más rápido que Invoke, aunque Invoke tiene una actualización más fluida. ¿Cómo puedo hacer que BeginInvoke "descargue los mensajes" en la pantalla? Hubo una idea en alguna otra publicación en la que puedo guardar los puntos en una cola y dibujar en la pantalla mientras todavía hay algo en la cola, pero no hubo ninguna diferencia. Por favor, ¿alguna idea? Gracias.

preguntado el 11 de junio de 12 a las 19:06

El mecanismo Dispatcher no es realmente ligero. Si tiene que llamarlo varias veces, puede considerar crear una cola segura para subprocesos y BeginInvoke un solo método ProcessAllItems. -

1 Respuestas

Según MSDN Control.BeginInvoke ():

Ejecuta un delegado de forma asincrónica en el subproceso en el que se creó el identificador subyacente del control.

En su caso, llamar repetidamente a BeginInvoke está agregando muchas llamadas al subproceso de la interfaz de usuario PRINCIPAL, atascándolo con otro trabajo.

Definitivamente, es mejor agrupar sus puntos en una cola y luego dibujarlos en la pantalla a la vez, en lugar de intentar tener múltiples sorteos ejecutándose de forma asíncrona en el mismo hilo.

Respondido el 11 de junio de 12 a las 19:06

No puede tener "múltiples sorteos ejecutándose de forma asincrónica en el mismo hilo", un hilo solo puede hacer una cosa a la vez. Pero tiene razón en que está enviando muchos mensajes innecesarios al subproceso de la interfaz de usuario, donde ponerlos en cola y procesarlos todos a la vez probablemente reduciría el "retraso" que ve (aunque probablemente no lo eliminará por completo si está haciendo tantas actualizaciones a la vez que congela el subproceso de la interfaz de usuario por completo). - CodificaciónGorilla

Si tengo que ponerlos en cola una vez, definitivamente no responderá. ¿Cómo puedo tener el lote para que se actualice cuando haya suficientes cosas? Intenté usar un temporizador, si temporizador> código básico de maxTimer para actualizarlo, pero eso no ayudó. Intenté verificar el tamaño de la cola para ver si es 500 y luego actualicé. Pero estas no son soluciones óptimas. - lews therin

¿Se está procesando otro código, además del dibujo real de los objetos del juego? Si es así, podría mover esa lógica a un subproceso de trabajo separado y hacer que el subproceso de la interfaz de usuario solo maneje el dibujo real. - Jon Senchyna

@LewsTherin no necesita procesarlos todos juntos. Puede procesarlos uno por uno de manera cooperativa con el subproceso principal (stackoverflow.com/questions/4502037/…) si, y solo si, realmente necesita hacerlo en el subproceso de la interfaz de usuario. - Adriano Repetti

Application.DoEvents no existe en WPF. Y escuché que es una señal de mal diseño. 1 hilo es rápido, si puedo conseguir que sea suave para varios hilos, me alegraré. Intenté manejarlo usando eventos, pero aún termino teniendo que llamar a invocar/comenzar a invocar - lews therin

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.