2010-05-19 20 views
7

Así que me han dicho que lo que estoy haciendo aquí está mal, pero no estoy seguro de por qué.¿Los hilos de fondo son una mala idea? ¿Por qué?

Tengo una página web que importa un archivo CSV con números de documentos para realizar una operación costosa. Puse la costosa operación en una cadena de fondo para evitar que bloqueara la aplicación. Esto es lo que tengo en pocas palabras.

protected void ButtonUpload_Click(object sender, EventArgs e) 
{ 
    if (FileUploadCSV.HasFile) 
    { 
     string fileText; 
     using (var sr = new StreamReader(FileUploadCSV.FileContent)) 
     { 
      fileText = sr.ReadToEnd(); 
     } 

     var documentNumbers = fileText.Split(new[] {',', '\n', '\r'}, StringSplitOptions.RemoveEmptyEntries); 

     ThreadStart threadStart =() => AnotherClass.ExpensiveOperation(documentNumbers); 
     var thread = new Thread(threadStart) {IsBackground = true}; 
     thread.Start(); 
    } 
} 

(obviamente, con un poco de comprobación de errores & mensajes para los usuarios tirado)

Así que mi pregunta es triple:

  • a) ¿Es esta una mala idea?
  • b) ¿Por qué es esta una mala idea?
  • c) ¿Qué harías en su lugar?

Respuesta

8

Un posible problema es que el hilo de fondo se está ejecutando en el grupo de aplicaciones de sitios web. IIS puede decidir reciclar su grupo de aplicaciones causando que la costosa operación se elimine antes de que finalice.

Preferiría ir por una opción en la que tuviera un proceso separado, posiblemente un servicio de Windows, que obtuviera las costosas solicitudes de operación y las realizara fuera del proceso asp.net. Esto no solo significa que su costosa operación podría sobrevivir a un reinicio del grupo de aplicaciones, sino que también simplificaría su aplicación web ya que no tenía que manejar el procesamiento.

Decirle al servicio que realice el costoso proceso podría hacerse utilizando algún tipo de comunicación entre procesos, el servicio podría sondear una tabla de base de datos o un archivo, o podría usar una cola de administración que el servicio escucharía.

Hay muchas maneras de hacerlo, pero mi punto principal es que debe separar el costoso proceso de su aplicación web si es posible.

1

a: yes.

Use ThreadPool;) Queue a WorkItem - evita la sobrecarga de generar toneladas de hilos.

7

Te recomiendo que uses la clase BackgroundWorker en lugar de usar hilos directamente. Esto se debe a que BackgroundWorker está diseñado específicamente para realizar operaciones de fondo para una aplicación gráfica, y (entre otras cosas) proporciona mecanismos para comunicar actualizaciones a la interfaz de usuario.

+0

Pero 'BackgroundWorker' usa subprocesos' ThreadPool', que no deben usarse para operaciones de larga ejecución. – Toby

+0

¿Tiene una referencia para esto? –

+0

También depende de la definición de "larga duración". Hay una diferencia entre "lo suficientemente largo como para no hacer que el usuario se siente y esperar" y "horas o días". –

Cuestiones relacionadas