2011-01-19 16 views
5

ho questo metodo [HttpPost] azione:Posso/devo utilizzare un controller asincrono qui? (ASP.NET MVC 3)

[HttpPost] 
public ActionResult AddReview(Review review) 
{ 
    repository.Add(review); 
    repository.Save(); 
    repository.UpdateSystemScoring(review.Id); // call SPROC with new Review ID. 
    return View("Success", review); 
} 

Quindi, in pratica un utente fa clic su un pulsante, lo aggiungo al mio database (tramite Entity Framework 4.0), salvare le modifiche, e quindi io chiamo una procedura memorizzata con il campo identità, che è la penultima riga di codice.

Questo deve essere fatto dopo la revisione è salvato (come il campo di identità si crea solo una volta Salva si chiama, e EF persiste le modifiche), e si tratta di un livello di sistema di calcolo.

Dal punto di vista utente, lui/lei non/non dovrebbe preoccuparsi che questo calcolo stia accadendo.

Questa procedura può richiedere da 0 a 20 secondi. Non restituisce nulla.

È un candidato per un controller asincrono?

C'è un modo posso aggiungere la revisione, e lasciare che un altro controller asincrono gestire la chiamata di lunga durata SPROC, così l'utente può essere preso alla pagina di successo immediatamente?

devo ammettere (parzialmente vergogno di questo): questa è una riscrittura di un sistema esistente, e nel sistema originale (Web Form ASP.NET), i sparò un altro filo per realizzare l'operazione di cui sopra - motivo per cui mi chiedevo se lo stesso principio può essere applicato a ASP.NET MVC 3.

Io sempre provare ed evitare il multi-threading in ASP.NET ma l'esperienza utente è la priorità numero 1 e io non voglio che la pagina termini.

Quindi - è possibile? Sono anche felice di sentire altre idee. Inoltre, non posso usare i trigger qui, non voglio davvero entrare troppo nel dettaglio del perché - ma non posso.

risposta

4

Vorrei attivare un nuovo thread (non dal pool di thread) per eseguire questa attività e restituire immediatamente soprattutto se non ti interessa i risultati. I controller asincroni sono utili in situazioni in cui la maggior parte del tempo è trascorso in attesa che qualche altro sistema completi l'attività e una volta che questo sistema ha completato l'attività, l'applicazione viene segnalata per elaborare il risultato. Durante l'esecuzione dell'attività non vengono utilizzati thread dall'applicazione. Pertanto, nel proprio scenario questa attività potrebbe essere eseguita da SQL Server utilizzando le versioni asincrone dei metodi BeginRead in ADO.NET. Potresti usarlo se hai bisogno dei risultati. Se non si attiva una nuova discussione funzionerebbe bene come prima.

+0

Davvero? Quando inizialmente ho proposto di farlo (nella versione originale del sistema), sono stato crocifisso da John Saunders e mi è stato chiesto di "leggere su ASP.NET". E sì - non mi interessa il risultato. SPROC non restituisce nulla - apporta solo modifiche ai dati. Quindi - consiglieresti di sparare una discussione come prima? – RPM1984

+0

E cosa intendi con "non dal pool di thread?". Precedentemente stavo semplicemente facendo 'new Thread()', imposta il metodo, passavo i parametri dell'array, ecc. – RPM1984

+0

@ RPM1984, ASP.NET utilizza un pool di thread per soddisfare le richieste. Ci sono thread preinitializzati in questo pool e quando una richiesta arriva in ASP.NET disegna un thread da questo pool. Non crea un nuovo thread perché potrebbe essere costoso. Fare 'new Thread()' è ok perché stai creando un nuovo thread. Potresti anche indicare il post in cui hai * crocifisso * di John Saunders? –

1

Poiché il sistema di valutazione impiega così tanto tempo per l'esecuzione, è consigliabile utilizzare un'attività pianificata in SQL Server o Windows per aggiornare i punteggi ogni x minuti di minuti. Poiché l'utente non è a conoscenza della richiesta, non è importante eseguirlo immediatamente.

È possibile aggiungere gli ID a una coda ed elaborare la coda ogni 30 minuti.

In caso contrario, se è necessario eseguire immediatamente una chiamata, è possibile effettuare una chiamata asyn o verificare se è possibile ridurre il grasso del processo memorizzato.

1

Penso che i controller asincroni siano di più per le cose in cui la richiesta potrebbe richiedere molto tempo per restituire una risposta, ma il thread principale passerebbe la maggior parte del tempo in attesa di un altro thread/processo. Ciò è utile soprattutto per le chiamate Ajax piuttosto che per il caricamento della pagina principale, quando è accettabile mostrare solo un indicatore di avanzamento fino a quando la risposta non viene restituita.

Uso un sistema di accodamento separato per questo tipo di attività, che è più robusto e più facile da utilizzare, ma richiede un po 'più di lavoro per la configurazione. Se hai davvero bisogno di farlo all'interno del processo ASP.net, una richiesta separata è probabilmente l'opzione migliore, anche se è possibile che l'attività non venga eseguita, ad esempio non sono sicuro di cosa succederebbe se la connessione dovesse cadere o se la il pool di app si ricicla mentre è in esecuzione un'attività asincrona.

+0

Sì, non volevo toccare l'architettura del sistema, motivo per cui sto cercando di evitare un sistema di accodamento (servizio wcf, broker sql server, ecc.). – RPM1984

1

Ho un sistema molto simile che ho scritto. Invece di fare le cose in modo sincrono, facciamo tutto asincrono usando le code.

Action -> causes javascript request to web server 
    | 
Web server puts notification on queue 
    | 
Worker picks up message from queue and does point calculation 
    | 
At some point in future user sees points adjusted 

Questo ci permette di essere in grado di gestire grandi quantità di carico di utenti e non è necessario preoccuparsi di questo avere un effetto negativo sul nostro motore di calcolo. Ciò significa anche che possiamo aggiungere più lavoratori per gestire un carico maggiore quando abbiamo un carico elevato e possiamo rimuovere i lavoratori quando non abbiamo un carico elevato.

Problemi correlati