¿Cómo debo realizar una tarea larga en ASP.NET 4?

Estoy construyendo un sitio web usando .NET 4. Hay muchos artículos de MSDN que datan de 2003, sobre el uso de Thread objects y 2007, que usan Asynchronous Pages en .NET 2 , pero eso está bastante pasado de moda. Sé que .NET 4 nos trajo la clase Tarea y algunas personas advirtieron vagamente contra su uso para este propósito .

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

EDIT: Ok, ok, 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?

    Preferencialmente, evite ejecutar tareas largas en dicho entorno.

    Delegue tareas de larga ejecución en 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 fallar, pero las circunstancias que rodean tal evento en un sistema diseñado para ser persistente 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.

    Lo mejor es evitarlo, pero si se lo fuerza a hacerlo, considere las ideas de Hanselman en Cómo ejecutar tareas en segundo plano en ASP.NET .

    Entre ellos, y para algo rápido y fácil, le sugiero que busque en particular en el QueueBackgroundWorkItem agregado en 4.5.2.

    Por experiencia personal, Tarea no lo corta. QueueBackgroundWorkItem es mucho mejor.

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

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

    Todavía puede usar la Biblioteca de tareas paralelas , pero la tarea se inicia en un proceso separado fuera de IIS (la razón es que IIS tiene un número limitado de subprocesos de trabajo para distribuir e impone otras limitaciones que pueden hacer que las tareas de larga ejecución sean impredecibles).

    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 temporizador delegado, deberá 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 últimoInvokeDay debe persistir en la base de datos o en un archivo ...

    Ahora, si desea habilitar la invocación inmediata de la tarea, simplemente puede llamar a 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 de lock ) y mover la lastInvokeDay dentro.

    ¿Responde esto a tu pregunta?