2010-02-09 19 views
7

He escrito una aplicación .NET winforms que utiliza un subproceso secundario para hacer un procesamiento pesado, que comunica su progreso al subproceso de la interfaz de usuario. Todo funciona correctamente, el formulario muestra el progreso, y también he creado un botón de cancelar para interrumpir el hilo de procesamiento. Sin embargo, cuando el proceso consume mucho tiempo, la aplicación y toda mi computadora se ralentizan. Lleva mucho tiempo arrastrar las ventanas, e incluso hay un retraso significativo al intentar escribir letras en el bloc de notas.Cambiar la prioridad de subprocesos para que mi programa y computadora sean más receptivos

Supongo que necesito reducir la prioridad del subproceso de procesamiento y/o aumentar la prioridad del subproceso de UI. ¿Es esto correcto? En este momento ambos hilos son prioridad normal.

¿Es tan fácil como el siguiente? ¿O hay algo más que debería hacer?

Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; 

¿Cómo debo modificar las prioridades? ¿Debo reducir la prioridad del procesamiento, o aumentar la prioridad de la interfaz de usuario, o ambas cosas? ¿Y a qué escenario? Por encima de Normal, o más alto?

+0

Eric, ¿qué tipo de procesador hay en su máquina de desarrollo? ¿Con qué frecuencia el hilo de trabajo se comunica a la UI? – overslacked

Respuesta

0

Por lo general, desea dejar solo la prioridad de su hilo principal y reducir la prioridad de la cadena de procesamiento a Inactivo.

+0

Establecerlo en inactivo hará que una rutina de larga ejecución y de gran computación tarde mucho, potencialmente. Mejor configurarlo BelowNormal. –

+0

@Reed: normalmente no habrá ninguna diferencia entre los dos. La única forma de que haya alguna diferencia es si hay otro hilo en la prioridad Idle o BelowNormal, ninguno de los cuales es particularmente común. –

+0

Hay bastantes servicios establecidos en BelowNormal. De hecho, he encontrado una diferencia notable en mi código ... –

1

Si desea que el hilo de fondo no afecte la capacidad de respuesta del sistema como un todo, deberá disminuir su prioridad, muy probablemente estableciendo su Prioridad en BelowNormal.

De lo contrario, tendrá el mismo efecto que está viendo actualmente.

Habiendo dicho esto, dudaría en hacer esto en mi propio código. Si su programa se ejecuta en un sistema con más núcleos de procesamiento, es probable que esto no sea un problema, y ​​al disminuir la prioridad del hilo (potencialmente) su algoritmo tardará más en procesarse.

5

No creo necesariamente que la prioridad de subprocesos sea su problema (aunque podría ser parte de esto). Eche un vistazo a esta pregunta SO: Background Worker Thread Priority.

Es probable que los bucles excesivamente apretados en el hilo de fondo que están manteniendo el tiempo de CPU en ese hilo. Hay varias maneras de solucionarlo desde el brutal (thread sleeps) hasta el más razonable (mutexs y eventos).

También puede intentar perfilar el hilo de fondo (directamente o en un arnés de prueba) para ver dónde está pasando la mayor parte de su tiempo, y tratar de aislarlo con eventos asíncronos o técnicas similares de descarga.

+0

+1 - esta es la mejor solución – Tim

+0

Si el trabajo es realmente "procesamiento pesado", como se especifica, entonces tratar de usar mutexes y eventos, etc., simplemente ralentizará drásticamente el procesamiento. Usar su CPU al máximo no es algo malo, usarlo innecesariamente es el problema ... –

+0

Depende de la definición de "procesamiento pesado". Aunque estoy de acuerdo con usted en que Reed, si ya tiene una fuerte inversión, agregar interruptores de contexto adicionales empeorará las cosas. Sin embargo, mi experiencia ha sido que a veces la segmentación de trabajo cuidadosamente aplicada (usando mutexes y señales) puede aliviar la contención del procesador, sin afectar significativamente la velocidad, aunque siempre habrá alguna pérdida. – GrayWizardx

0

Normalmente, debe establecer la prioridad del subproceso de trabajo en un nivel agradable (por ejemplo, el usuario puede querer hacer algo en otra aplicación e incluso el subproceso de trabajo debe jugar bien) aunque Windows ya impulsa los procesos "activos" hilo (la aplicación tiene una ventana con enfoque de entrada) un poco para que se sienta más receptivo. Las prioridades más altas generalmente se necesitan cuando necesita cumplir con algunas limitaciones de tiempo.

+0

También una nota (no el problema principal): debe tener en cuenta que tener subprocesos con prioridades diferentes puede producir problemas de simultaneidad extraños (cosas como: qué pasa si un subproceso con un prio inferior toma una sección crítica y nunca se vuelve a programar porque es normal o thread prio superior toma toda la CPU) –

+0

@Ritsaert: el programador de Windows tiene "prevención de inanición", por lo que incluso si se establece algo como de baja prioridad, ocasionalmente se "golpeará" su prioridad para que se ejecute y (eventualmente) libere la sección crítica/mutex/lo que sea que contenga. –

+0

@Jerry: Gracias por la adición. Sé que las versiones más nuevas de Windows tienen eso, pero incluso con eso en su lugar puede mantener cerraduras durante mucho tiempo (hablando en términos relativos) –

Cuestiones relacionadas