2011-04-05 11 views
8

Estoy construyendo un sitio web usando .NET 4. Hay muchos artículos de MSDN que datan de 2003, about using Thread objects y 2007, using Asynchronous Pages in .NET 2, pero eso está muy pasado de moda. Sé que .NET 4 nos trajo el Task class y el some people vaguely cautioning against its use for this purpose.¿Cómo debo realizar una tarea larga en ASP.NET 4?

Así que le pregunto, ¿cuál es el método "preferido" alrededor del año 2011 para ejecutar el trabajo de fondo/asincrónico bajo IIS en ASP.NET 4? ¿Qué advertencias hay sobre usar Thread/Task directamente? Es Async = cierto todavía en boga?

EDITAR: Ok, de acuerdo, de las respuestas está claro que la opinión es que debería hacer un servicio si puedo. Pero las ventajas de hacerlo dentro de la aplicación web son importantes, especialmente una implementación/redistribución más fácil. Suponiendo que el proceso sea seguro para colgar, entonces, si tuviera que hacerlo dentro de IIS, ¿cuál es la mejor manera?

Respuesta

15

Preferentemente, evite que se ejecuten tareas largas en dicho entorno.

Delega las tareas de larga ejecución a un servicio de sistema estable a través de la interoperabilidad, dejando la aplicación web receptiva y solo requerida para las solicitudes directas de los usuarios.

Las aplicaciones web nunca se han considerado (y aún no se consideran) sistemas confiables; cualquiera que haya usado alguna vez un navegador se ha encontrado (al menos) con un tiempo de espera, sin duda; y tal inconveniente (para ambas partes) no se limita a este escenario. Por supuesto, cualquier sistema puede bloquearse, pero las circunstancias que rodean tal evento en un sistema built-to-persistent deben ser completamente excepcionales.

Los servicios de Windows están diseñados para ser de larga duración, y si algo sale mal, generalmente tiene más de qué preocuparse que su servicio individual.

+0

En WAWS, utilizar Azure WebJobs – RickAndMSFT

0

Mi método preferido es el mismo que Robert Harvey propone en su respuesta.

Puede seguir utilizando el Task Parallel Library, pero girar la tarea en un proceso separado fuera de IIS (la razón es que IIS tiene un número limitado de subprocesos de trabajo para repartir e impone otras limitaciones que pueden hacer tareas de larga ejecución impredecible)

+0

¿Tiene un ejemplo rápido de esto? – Tigran

0

Puede crear un ThreadPool estático como este http://www.dotnetperls.com/threadpool con número de hilos limitado (por ejemplo, solo 2). y luego poner tareas en cola, pero no es recomendable porque los servidores web no son para este tipo de tareas

0

Esta es una descripción de un escenario de "una vez al día".

Si realmente desea evitar la creación de un servicio, puede iniciar un temporizador con intervalos de 1 minuto. Cada vez que se invoca el delegado de temporizador, tendrá que ejecutar algo como esto (pseudo código):

lastInvokeDay = LoadLastInvokeDate(); 
If (lastInvokeDay < DateTime.Now.Date && timeOfDayToRun == DateTime.Now.Time) 
{ 
    try 
    { 
    today = DateTime.Now.Date; 
    runMyTask(); 
    } 
    catch.. 
    finally 
    { 
    lastInvokeDay = today; 
    SaveLastInvokeDay(lastInvokeDay); 
    } 
} 

Tenga en cuenta que el lastInvokeDay debe persistir, ya sea en base de datos o en un archivo ...

Ahora, si desea habilitar la invocación inmediata de la tarea, simplemente puede llamar al runMyTask() bajo demanda. Si es importante para usted evitar que runMyTask ocurra más de una vez al día, puede crear un bloque de código sincronizado dentro de él (con una instrucción lock) y mover el cheque lastInvokeDay dentro.

¿Responde a esta pregunta?

1

Es mejor evitar, pero si se ven obligados a, tenga en cuenta los pensamientos de Hanselman en How to run Background Tasks in ASP.NET.

Entre ellos, y para algo rápido y fácil, sugeriría nos fijamos en particular, en el QueueBackgroundWorkItem añadido en 4.5.2.

Por experiencia personal, tarea no es suficiente. QueueBackgroundWorkItem es mucho mejor.

Cuestiones relacionadas