2012-06-01 16 views
11

Ho bisogno di eseguire un ciclo while infinito e voglio iniziare l'esecuzione in global.asax. La mia domanda è come esattamente dovrei farlo? Devo iniziare una nuova discussione o dovrei usare Async e Task o altro? All'interno del ciclo while devo fare await TaskEx.Delay(5000);Implementare correttamente il processo in background Thread in ASP.NET

Come faccio a fare questo in modo che non bloccherà nessun altro processo e non creerà perdite di memoria?

Io uso VS10, AsyncCTP3, MVC4

EDIT:

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

Tutto quello che devi fare è eseguire questo come istanza Singleton a livello globale finché applicazione è disponibile.

EDIT: Risolto

Questa è la soluzione finale di 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 
    { 
      /// 
    } 
} 

ho trovato questo simpatico articolo su come utilizzare lavoratore asincrona: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

E questo: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Ma penso per il mio bisogno s questo sarà perfetto: http://forums.asp.net/t/1433665.aspx/1

+0

cosa stai cercando di fare? – jrummell

+1

Cosa fa Clients.SetConnectionTimeStamp? Qual è lo scopo di questo? Quale funzionalità specifica stai cercando di implementare? Se si desidera una risposta di qualità, è necessario fornire queste informazioni. – cadrell0

+0

Questo è meglio farlo con un timer. – Aristos

risposta

1

Ho trovato questo bell'articolo su come utilizzare async worker, provarlo. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

E questo: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Ma credo che per le mie esigenze questo sarà perfetto: http://forums.asp.net/t/1433665.aspx/1

+0

Attenzione: il ciclo infinito masticherà il processore. Inoltre, dovrai assicurarti di non avviare accidentalmente più istanze di queste cose (il che implica alcuni controlli multi-threading). – JDB

+0

@ Cyborgx37 Bene, questo è il motivo per cui ho pubblicato l'OP, ma sfortunatamente su SO c'è troppo rumore ... Inoltre se avessi letto l'OP da solo avresti saputo che il thread sarebbe stato messo a dormire così là non c'è nessun problema di CPU lì. –

13

ASP.NET non è progettato per gestire questo tipo di requisito. Se hai bisogno di qualcosa da eseguire costantemente, sarebbe meglio creare un servizio Windows.

Aggiornamento

ASP.NET non è progettato per attività in esecuzione lunghi. È progettato per rispondere rapidamente alle richieste HTTP. Vedere Cyborgx37's answer o Can I use threads to carry out long-running jobs on IIS? per alcuni motivi.

Aggiornamento

Ora che finalmente ha citato si sta lavorando con SignalR, vedo che si sta tentando di ospitare SignalR all'interno di ASP.NET, giusto? Penso che stai andando in questo modo sbagliato, vedi l'esempio NuGet package riferito allo project wiki. Questo esempio utilizza un IAsyncHttpHandler per gestire le attività.

+2

Il primo collegamento non fornisce alcun motivo per cui, il secondo link indica solo la preoccupazione evidente che il server potrebbe scegliere di riciclare il pool di applicazioni a un certo punto. Non ho ancora sentito una valida preoccupazione perché questa è una "cattiva idea". Per trasformare un elemento in un servizio di Windows, rendendo la tua applicazione molto più difficile da implementare, mi sembra una cattiva idea. Qualcuno ha una vera ragione o è solo un'ideologia? – John

+0

_... molto ovvio che il server potrebbe scegliere di riciclare il pool di app ad un certo punto_ Questo è un grosso problema ... – jrummell

+0

Tutte le applicazioni si fermano a un certo punto, che non è univoco per ASP.NET. Stai discutendo contro l'esecuzione di lavori in background nelle applicazioni WinForms perché l'utente può fare clic sul pulsante di chiusura in qualsiasi momento? Anche i servizi Windows devono andare giù quando il server viene riavviato. Come è diverso? – John

8

È possibile avviare una discussione in global.asax, tuttavia verrà eseguita solo fino a quando il processo asp.net verrà riciclato. Ciò avverrà almeno una volta al giorno o quando nessuno utilizzerà il tuo sito. Se il processo viene riciclato, l'unico modo in cui il thread viene riavviato, è quando si ha un impatto sul tuo sito. Quindi il thread non sta funzionando continuamente.

Per ottenere un processo continuo è meglio avviare un servizio di Windows.

Se si esegue la soluzione "In processo", dipende molto da ciò che si sta facendo. Il thread stesso non causerà alcun problema di memoria o deadlock. È necessario aggiungere un meganism per interrompere il thread quando l'applicazione si interrompe. In caso contrario, il riavvio richiederà molto tempo, poiché attenderà il blocco del thread.

+1

Eccellente! Non ho problemi a riciclarli. Questo è uno dei requisiti. –

+0

Grazie! Ho modificato la mia domanda con maggiori dettagli. –

+0

Sono d'accordo con il pari. La soluzione e un avvertimento sui pericoli di questo possono essere trovati in questo grande articolo: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in- asp-net.aspx/ –

2

Dipende da ciò che stai cercando di ottenere nel tuo ciclo while, ma in generale questo è il tipo di situazione in cui una Windows Service è la risposta migliore. L'installazione di un servizio di Windows richiede il possesso di privilegi di amministratore sul server web.

Con un ciclo infinito si finisce con un sacco di problemi che riguardano il pump dei messaggi di Windows. Questa è la cosa che mantiene in vita un'applicazione Windows anche quando l'applicazione non sta "facendo" nulla. Senza di esso, un programma finisce semplicemente.

Il problema con un ciclo infinito è che l'applicazione è bloccata "facendo" qualcosa, che impedisce ad altre applicazioni (o thread) di "fare" la loro cosa. Ci sono state alcune soluzioni alternative, come DoEvents in Windows Form, ma hanno tutti alcuni seri svantaggi quando si tratta di reattività e gestione delle risorse. (Accettabile su una piccola applicazione LOB, forse non su un server Web.) Anche se il ciclo while si trova su un thread separato, utilizzerà tutta la potenza di elaborazione disponibile.

La programmazione di Asynchronus è davvero progettata per processi a esecuzione prolungata, come l'attesa di un database per restituire un risultato o l'attesa di una stampante in linea. In questi casi, è il processo esterno che richiede molto tempo, non un ciclo temporale.

Se un servizio di Windows non è possibile, penso che la soluzione migliore sarà impostare un thread separato con la propria pompa di messaggi, ma è un po 'complicato. Non l'ho mai fatto su un server web, ma potresti essere in grado di avviare un'applicazione. Ciò fornirà un messaggio per te e ti consentirà di rispondere agli eventi di Windows, ecc. L'unico problema è che avvierà un'applicazione Windows (WPF o WinForms), che potrebbe non essere consigliabile su un server web.

Cosa stai cercando di realizzare? C'è un altro modo per affrontarlo?

+0

Grazie! Ho modificato la mia domanda con maggiori dettagli. –

Problemi correlati