2009-02-07 11 views
8

Estoy tratando de utilizar el objeto .NET Backgroundworker en una aplicación que estoy desarrollando.Prioridad de subproceso del objeto .NET Backgroundworker

Todo el material en Internet dice que este objeto se ejecuta en el "fondo" pero en ninguna parte he podido confirmar que este hilo de fondo efectivamente se ejecuta en un modo de "baja prioridad". Esta pregunta surge porque en Windows (supongo) una tarea en segundo plano puede ejecutarse en un modo de prioridad 'normal' o 'por debajo de lo normal' o 'bajo'.

En mi solicitud, me trataron de establecer la prioridad a mí mismo dentro de la función DoWork llamando ...

Thread.CurrentThread.Priority=ThreadPriority.Lowest 

...

pero esto parece tener ningún efecto. ¿El trabajador de fondo ignora esta llamada?

me gustaría explicar un poco más:

Mi aplicación es un cliente de Internet que recoge datos en tiempo real de la temperatura, etc humedad de una cámara y subidos a una página web (no es un servicio web) usando

system.net.webclient.UploadValuesAsync(...) llama

he escrito la solicitud de tal manera que la GUI del cliente recoge los datos de la cámara, ellos sellos de tiempo y luego los pone en cola para subir al igual que

...

Synclock objlock 
    debug.print("Queueing reading...") 
    dataQ.Enque(reading) 
End Synclock 
... 

Retiros de cola de función DoWork del BackgroundWorker y luego lo carga como así ...

..............

Do 
     if dataQ.count() <> 0 then 
      Synclock objlock 
       reading = dataQ.DeQue() 
      End Synclock 
      Dim client As New System.Net.WebClient 
      ...put the reading in NameValueCollection and upload to server page 
      req = new NameValueCollection 
      ... 
      ... 
      client.UploadValuesAsync(uri, "POST", req) 
     endif 
     thread.sleep(1) 'without this line the CPU usage goes upto 100% and seems to slow other tasks! 
    Loop 

..... ...........

Cuando ejecuto el programa me parece que cada vez que se llama a UploadValuesAsync se imprime la ventana de depuración se detiene. También agregué declaraciones de depuración para ver cuántas lecturas hay en la cola en cualquier momento. Si esta tarea se ejecuta realmente con baja prioridad, esperaba ver que el recuento de colas aumenta rápidamente a medida que se adquieren los datos y luego disminuyen solo cuando el primer plano está inactivo y no se están adquiriendo datos. Pero este no es el caso. Tan pronto como se agrega una lectura a la cola, se quita de la cola y se carga. ¡Entonces el recuento de cola siempre es 1 o 0!

¿Hay algo mal en mi enfoque? ¿No debería usar el objeto de fondo de trabajo?

Por cierto, esto es en una computadora portátil de doble núcleo con Windows XP.

Respuesta

13

Sólo para añadir a lo que Jon y Marc ya han dicho: hilos

de fondo no tienen una prioridad más baja. La diferencia entre los hilos de primer plano y de fondo es que el CLR cerrará el proceso una vez que no se estén ejecutando más hilos de primer plano. Los subprocesos del grupo de subprocesos son subprocesos de fondo.

Puede establecer la prioridad de un subproceso de grupo de subprocesos, pero como no tiene control sobre qué subproceso del subproceso ejecutará su tarea, no es aconsejable hacerlo. Si necesita hilos de una prioridad específica, debe crearlos utilizando el tipo de subproceso y establecer la prioridad en la instancia como desee.

+1

¿Cómo es que no puedo etiquetar TODAS las respuestas como útiles? ¡Cada uno de ellos tiene algunas sugerencias útiles ...! –

+2

Solo puede seleccionar una respuesta, pero puede votar todas las respuestas que encuentre útiles. –

3

No pretende ser de baja prioridad - background significa a: no el subproceso de interfaz de usuario, y b: no mantendrá un proceso vivo. En realidad, probablemente se relaciona con los hilos ThreadPool.

Si quieres un subproceso de prioridad específica, a continuación, utilizar su propio objeto Thread - pero yo no recomendaría incluso esto normalmente ...

Además - "fondo" no quiere decir "cuando esté inactivo". Incluso en una máquina de núcleo único, probablemente verá que ambos hilos obtienen la mayor cantidad de tiempo (si lo desean). Aún más en multi-core.

+0

El problema es cuando el subproceso de fondo está llamando a la UploadAsync, parece estar bloqueando/ralentizar el hilo de interfaz de usuario. Puedo decir esto porque las sentencias de depuración se detienen cuando ocurre la carga. ¿Cómo puedo evitar esto? –

+0

¿Cuántos núcleos tienes? El trabajo tiene que suceder en alguna parte ... –

+0

Es una computadora portátil de doble núcleo con Win XP. –

7

Sí, algo anda mal con tu enfoque: básicamente estás apretado cuando la cola está vacía. Cualesquiera que sean las prioridades del hilo, esa es una mala idea.

No hay nada malo con el uso de un asistente de fondo para esto, pero el enqueuing/dequeuing solo debería usar una cola de productor/consumidor que bloquea cuando intenta dequeue cuando no hay nada preparado.

Tengo una implementación de ejemplo de una cola de productor/consumidor in my threading tutorial - mire aproximadamente a la mitad de la página enlazada. Por cierto, querrás decir de alguna manera el proceso de eliminación de que está terminado. (Por ejemplo, poner en cola una referencia nula u otro valor especial). Ese código fue escrito pre-genéricos, pero debería ser fácil de actualizar.

+0

En su ejemplo, espera 10 elementos en la cola y el hilo consumidor finaliza cuando quita 10 elementos. En mi caso, los elementos se agregan a la cola a lo largo del ciclo de vida de la aplicación (aproximadamente 10 elementos por segundo), por lo que oWork nunca debe terminar. Entonces, ¿qué otra cosa hacer sino un circuito cerrado? –

+0

@Soundar: la única diferencia es la condición de terminación. Como sugerí en la respuesta, podría usar un valor especial (por ejemplo, nulo) para indicar la terminación, o simplemente nunca terminar. Lo importante es bloquear (en lugar de bucles) cuando no hay entradas. –

+0

Gracias. Sobre la lectura adicional de sus tutoriales, ahora sé lo que hice mal. Debería usar Monitor.sleep en lugar de thread.sleep (me preguntaba por qué necesitaba eso de todos modos). Y monitor.wait parece funcionar dentro de la función DoWork. –

Cuestiones relacionadas