L'invio di messaggi di posta elettronica di massa in background - Crea Discussione o utilizzare ThreadPool?

StackOverflow https://stackoverflow.com/questions/4138405

Domanda

Ho un'applicazione in cui l'azione fa scattare una serie di e-mail da inviare. Il numero di e-mail è variabile e può essere ovunque da 10 a 1.000 per azione .

Non voglio l'applicazione per blocco , mentre i messaggi di posta elettronica vengono inviati (in tal modo fastidioso l'utente) e vorrebbero inviargli il presente sullo sfondo.

Non ho usato le discussioni in passato, quindi è per questo che ho bisogno del vostro aiuto. Volete creare thread manualmente o si tratta di un buon caso di usare un ThreadPool? Voglio che questo compito sia bassa priorità e utilizzare il minor numero di risorse possibili, perché non mi dispiace anche se l'e-mail è di 1 ora di ritardo.

Apprezzo il vostro aiuto
Marko

È stato utile?

Soluzione

Qui va un altro suggerimento ... Se si `re utilizzando un DB, creare un'attività (ad esempio creare una tabella che rappresenta un compito che deve essere fatto) in relazione con i messaggi che devono essere inviati e l'uso Quartz.NET o simili (si può creare un servizio di Windows troppo) che cerca compiti incompleti e li esegue (contrassegnandoli come fatto nel caso in cui vengono eseguiti con successo).

Altri suggerimenti

In verità, la filettatura in ASP.NET non è una buona idea. Asp.net fa un sacco di smaltimento delle risorse quando una richiesta finisce e post indietro per l'utente. Dal momento che non si desidera che l'utente di attendere, si incorrerà in questo scenario, in cui ASP.NET oggetti si pensa sono sicuri da usare, sono realmente smaltito.

La soluzione migliore è quella di creare un servizio esterno (o un servizio WCF in esecuzione in IIS, o di un servizio di Windows che ha un'interfaccia WCF esposto), che nella pagina .net può chiamare in modo asincrono, e che hanno run richiesta fino al completamento. Non preoccuparsi di threading, ecc Funziona nel proprio processo di esso e quando è fatto che completa. Dal momento che non si cura di dire all'utente che ha fatto, non dovrete preoccuparvi di questo comunicare indietro. Questo modo di, se avete bisogno di avere altri impieghi pagina la stessa interfaccia di servizio, è lì per essere chiamato.

Pagine su come iniziare con WCF:

http://bloggingabout.net /blogs/dennis/archive/2007/04/20/wcf-simple-example.aspx

http://msdn.microsoft.com/en-us/library /bb332338.aspx

http://www.c-sharpcorner.com /Articles/ArticleListing.aspx?SectionID=1&SubSectionID=192

Come iniziare ad utilizzare WCF / WPF?

Quindi il mio suggerimento è quello di utilizzare ThreadPool. Sarebbe consentono di coda tutto invece per eseguire ciascuno di essi separatamente, il che rende utilizzare meno risorse, ma, naturalmente, prendendo più tempo per processo di tutto, ma come hai detto tu, il tempo non è un problema.

Si potrebbe semplicemente utilizzare il BackgroundWorker classe.

La pagina di MSDN collegata ha un bell'esempio con la segnalazione il progresso e la possibilità di annullare l'operazione.

Modifica
Relazione sull'andamento dei lavori e l'annullamento potrebbe non essere adatto in un'applicazione web, ma il BackgroundWorker gestisce tutta la roba sporca con la creazione di un thread per voi.

Edit2:
Se si desidera inviare molte mail in parallelo si può guardare la Task Parallel Biblioteca .

Si potrebbe usare Compiti per deporre le uova fuori il thread di lavoro per elaborare i messaggi di posta elettronica.

Se questo è martellare la CPU troppo, è possibile creare un nuovo scheduler che riduce la concorrenza: http://msdn.microsoft.com/en-us/library/ee789351.aspx

static void StartMailTasks(string[] addresses)
{
    List<Task> tasks = new List<Task>();
    foreach (var address in addresses)
    {
        tasks.Add(Task.Factory.StartNew(Email, address));
    }

    Task.Factory.ContinueWhenAll(tasks.ToArray(), AllDone, TaskContinuationOptions.OnlyOnRanToCompletion);
    Task.Factory.ContinueWhenAny(tasks.ToArray(), ReportError, TaskContinuationOptions.OnlyOnFaulted);
}

static void AllDone(Task[] tasks)
{
    // All is well
}

static void ReportError(Task errorTask)
{
    // Log or report the error
}

static void Email(object state )
{
    // send the e-mail  
    // Can throw error, if needed
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top