2012-06-01 12 views
11

Necesito ejecutar un ciclo while infinito y quiero iniciar la ejecución en global.asax. Mi pregunta es ¿exactamente cómo debería hacerlo? ¿Debo comenzar un nuevo Tema o debería usar Async y Tarea o cualquier otra cosa? Dentro del ciclo while necesito hacerlo await TaskEx.Delay(5000);Implementar correctamente el proceso de fondo Subproceso en ASP.NET

¿Cómo hago esto para que no bloquee ningún otro proceso y no cree pérdidas de memoria?

utilizo VS10, AsyncCTP3, MVC4

EDIT:

public void SignalRConnectionRecovery() 
     { 
      while (true) 
      { 
       Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString()); 
       await TaskEx.Delay(5000); 
      } 
     } 

Todo lo que necesito hacer es ejecutar esto como una instancia singleton a nivel mundial, siempre y cuando la aplicación está disponible.

EDIT: SOLUCIONADO

Ésta es la solución final en Global.asax

protected void Application_Start() 
{ 
    Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery); 
    signalRConnectionRecovery.IsBackground = true; 
    signalRConnectionRecovery.Start(); 

    Application["SignalRConnectionRecovery"] = signalRConnectionRecovery; 
} 


protected void Application_End() 
{ 
    try 
    { 
     Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"]; 
     if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive) 
     { 
      signalRConnectionRecovery.Abort(); 
     } 
    } 
    catch 
    { 
      /// 
    } 
} 

he encontrado este fantástico artículo sobre cómo utilizar asíncrono trabajador: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

Y esto: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Pero creo que para mi necesidad s éste será perfecto: http://forums.asp.net/t/1433665.aspx/1

+0

¿Qué está tratando de hacer? – jrummell

+1

¿Qué hace Clients.SetConnectionTimeStamp? ¿Cuál es el propósito de esto? ¿Qué funcionalidad específica estás buscando implementar? Si desea una respuesta de calidad, debe proporcionar esta información. – cadrell0

+0

Esto es mejor hacerlo con un temporizador. – Aristos

Respuesta

1

Encontré este artículo agradable sobre cómo usar el trabajador asincrónico, lo intentaré. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

Y esto: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Pero creo que para mis necesidades éste será perfecto: http://forums.asp.net/t/1433665.aspx/1

+0

Cuidado: el bucle infinito masticará su procesador. Además, deberá asegurarse de no iniciar accidentalmente varias instancias de estas cosas (lo que implica verificaciones de varios subprocesos). – JDB

+0

@ Cyborgx37 Bueno, esta es la razón por la que publiqué el OP, pero desafortunadamente en SO hay demasiado ruido ... Además, si hubieras leído el OP tú mismo, hubieras sabido que el hilo se dormirá durante mucho tiempo, así que no hay problema de CPU allí. –

13

ASP.NET no está diseñado para manejar este tipo de requisitos. Si necesita algo para ejecutar constantemente, sería mejor que cree un servicio de Windows.

actualización

ASP.NET no está diseñado para tareas de larga ejecución. Está diseñado para responder rápidamente a las solicitudes HTTP. Ver Cyborgx37's answer o Can I use threads to carry out long-running jobs on IIS? por algunas razones por qué.

actualización

Ahora que finalmente ha mencionado que está trabajando con SignalR, veo que usted está tratando de acoger SignalR dentro de ASP.NET, correcto? Creo que estás haciendo esto de la manera incorrecta; mira el ejemplo NuGet package al que se hace referencia en el project wiki. Este ejemplo usa un IAsyncHttpHandler para administrar tareas.

+2

El primer enlace no proporciona ningún motivo en absoluto, el segundo enlace solo indica la preocupación muy obvia de que el servidor pueda elegir reciclar el grupo de aplicaciones en algún momento. Todavía tengo que escuchar una preocupación válida por qué esta es una "mala idea". Para tener algo en cuenta en un servicio de Windows, hacer que su aplicación sea mucho más difícil de implementar, me suena como una mala idea. ¿Alguien tiene una razón real o es solo una ideología? – John

+0

_... preocupación muy obvia de que el servidor pueda elegir reciclar el grupo de aplicaciones en algún momento_ Eso es un gran problema ... – jrummell

+0

Todas las aplicaciones se caen en algún momento, eso no es exclusivo de ASP.NET. ¿Estás argumentando en contra de hacer trabajos en segundo plano en las aplicaciones de WinForms porque el usuario puede hacer clic en el botón de cerrar en cualquier momento? Incluso los servicios de Windows deben desactivarse cuando se reinicia el servidor. ¿Cómo es esto diferente? – John

8

Puede iniciar un hilo en su archivo global.asax, sin embargo, solo se ejecutará hasta que su proceso asp.net se recicle. Esto sucederá al menos una vez al día, o cuando nadie use su sitio. Si el proceso se recicla, la única manera en que se reinicia el hilo es cuando tiene un golpe en su sitio. Entonces, el hilo no se ejecuta continuamente.

Para obtener un proceso continuo, es mejor iniciar un servicio de Windows.

Si realiza la solución 'En proceso', realmente depende de lo que esté haciendo. El subproceso en sí no le causará ningún problema en la memoria o interbloqueos. Debe agregar un meganismo para detener su hilo cuando se detenga la aplicación. De lo contrario, reiniciar llevará mucho tiempo, porque esperará a que se detenga el hilo.

+1

¡Excelente! No tengo problemas para que se reciclen. Ese es uno de los requisitos. –

+0

¡Gracias! He editado mi pregunta con más detalles. –

+0

Estoy de acuerdo con el compañero. La solución y una advertencia sobre los peligros de esto se pueden encontrar en este gran artículo: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in- asp-net.aspx/ –

2

Depende de lo que intente lograr en su ciclo while, pero en general este es el tipo de situación en la que Windows Service es la mejor respuesta. La instalación de un Servicio de Windows requerirá que tenga privilegios de administrador en el servidor web.

Con un ciclo infinito, usted termina teniendo muchos problemas con respecto a la bomba de mensajes de Windows. Esto es lo que mantiene viva una aplicación de Windows incluso cuando la aplicación no está "haciendo" nada. Sin eso, un programa simplemente termina.

El problema con un bucle infinito es que la aplicación está bloqueada "haciendo" algo, lo que impide que otras aplicaciones (o subprocesos) "hagan" su trabajo. Ha habido algunas soluciones, como DoEvents en Windows Forms, pero todas tienen serias desventajas en lo que respecta a la capacidad de respuesta y la administración de recursos. (Aceptable en una aplicación LOB pequeña, tal vez no en un servidor web.) Incluso si el ciclo while está en una secuencia separada, agotará toda la potencia de procesamiento disponible.

La programación asincrónica está realmente diseñada más para procesos de larga ejecución, como esperar que una base de datos devuelva un resultado o esperar a que una impresora se conecte. En estos casos, es el proceso externo el que lleva mucho tiempo, no un ciclo while.

Si un servicio de ventana no es posible, entonces creo que su mejor opción será configurar un hilo separado con su propia bomba de mensajes, pero es un poco complicado. Nunca lo hice en un servidor web, pero es posible que pueda iniciar una Aplicación. Esto le proporcionará una bomba de mensajes y le permitirá responder a eventos de Windows, etc. El único problema es que esto iniciará una aplicación de Windows (ya sea WPF o WinForms), que puede no ser deseable en un servidor web.

¿Qué estás tratando de lograr? ¿Hay alguna otra manera de hacerlo?

+0

¡Gracias! He editado mi pregunta con más detalles. –

Cuestiones relacionadas