2009-08-23 20 views
26

Come è possibile implementare code di elaborazione in background nell'app Web ASP.NET MVC? Mentre la maggior parte dei dati cambia, gli aggiornamenti, ecc. Devono essere immediatamente visibili, ci sono altri aggiornamenti che non hanno bisogno di elaborazione in tempo reale che vorrei passare ad un processo in background con priorità più bassa che si prenderà cura di esso al proprio ritmo .Elaborazione in background in coda nell'applicazione Web ASP.NET MVC

Come esempio, prendere il sistema di assegnazione badge di StackOverflow. Di solito puoi intraprendere un'azione specifica che ti assegnerebbe un badge, ma il "premio" effettivo si verifica dopo (in genere tra 10 minuti e un paio d'ore dopo). Presumo che ciò avvenga tramite un processo di background separato, in quanto non è fondamentale per i lavori di SO assegnare i badge immediatamente quando vengono guadagnati.

Quindi, sto provando a creare un qualche tipo di sistema di coda in cui potrei riempire le attività (dite qualcosa che implementa l'interfaccia di ITask che avrà un metodo Process()) che alla fine verrà eseguito da un processo separato.

Come posso implementare tale sistema? Idee/suggerimento/codice di esempio?

Grazie!

risposta

20

Servizi Windows e MSMQ per comunicare con loro (se è addirittura necessario).

- Modifica

Per espandere leggermente.

Potrai creare diversi servizi, a seconda di cosa vuoi fare, e farli scorrere tutti infiniti di vari livelli di sonno, per fare quello che vuoi. Quindi aggiorneranno il database in modo appropriato e non avrai dovuto fare nulla dal lato client.

Si potrebbe desiderare di interagire con loro da un punto di vista amministrativo, quindi si può avere un MSMQ su cui ascoltano i comandi di amministrazione. A seconda dell'implementazione, potrebbe essere necessario riavviarli per qualche motivo o, eventualmente, semplicemente "forzare" l'esecuzione di ciò che desiderano.

Quindi si utilizzerà una coda privata MSMQ per farlo (spazio dei nomi System.Messaging). Una delle cose principali da notare su MSMQ, è che il messaggio deve essere < 4meg. Quindi se si intende inviare grafici di oggetti di grandi dimensioni, serializzarli in un file e inviare semplicemente il nome del file.

MSMQ è piuttosto bello. È possibile inviare sulla base di un 'ID di correlazione' se è necessario, ma, per qualche motivo divertente, l'ID di correlazione deve essere sotto forma di:

{guid}\1 

Tutto il resto non funziona (almeno nella versione 2.0 del framework, il codice potrebbe essere cambiato).

- Modifica

esempio, come richiesto:

using System.Messaging; 

... 


MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); 
queue.Formatter = new BinaryMessageFormatter(); 

Message m = new Message(); 
m.Body = "your serialisable object or just plain string"; 

queue.Send(m); 


// on the other side 

MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue"); 
queue.Formatter = new BinaryMessageFormatter(); 

Message m = queue.Receive(); 

string s = m.Body as string; 

// s contains that string now 
+1

Avete un esempio su come inizialmente un'applicazione di servizio 'connect' con un MSMQ e quindi ad ASP.NET MVC? Questo è abbastanza nuovo per me. Grazie! – Alex

+0

Basta scrivere sulla coda appropriata. Il tuo servizio chiamerà. Ricevi e la tua pagina, da cui vuoi inviare un messaggio alla coda, chiamerà semplicemente "Invia". Aggiornerò con un piccolo esempio –

+0

aggiornato. Nota Non ho mostrato il codice per creare la coda, se non esiste. Ma questo può essere trovato banalmente solo prendendo come l'API System.Messaging. In particolare: MessageQueue.Create (...). Nota che dovrai anche ottenere le autorizzazioni appropriate. (.SetPermissions). –

10

Jeff ha un grande post che mostra come ha raggiunto questo in origine per Stack Overflow in http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Anche se potrebbe non essere così affidabili come servizio se questa è un'opzione per te, mi è servita molto bene in passato per le attività non essenziali, e ho funzionato in un ambiente di hosting virtuale.

5

Trova questa domanda durante la ricerca del processo in background in ASP.NET MVC. (Disponibile dopo .NET 4.5.2)

public ActionResult InitiateLongRunningProcess(Emails emails) 
{ 
    if (ModelState.IsValid) 
    { 
     HostingEnvironment.QueueBackgroundWorkItem(ct => LongRunningProcessAsync(emails.Email)); 
     return RedirectToAction("Index", "Home"); 
    } 

    return View(user); 
} 

Nota: Personalmente non utilizzerò il server Web per eseguire attività in background. Inoltre, non reinventare la ruota, consiglio vivamente di utilizzare Hangfire.

Leggi questo articolo grande da Hanselman HowToRunBackgroundTasksInASPNET

Problemi correlati