3 messaggi dal 07 marzo 2015
Ciao a tutti!
Cercherò di essere conciso...
E' la prima volta che mi ci cimento, vorrei avere consigli...e delucidazioni...
In pratica, vorrei inviare mail di massa (Newsletter) pescando gli indirizzi da database...
Il problema nasce dai limiti dell'hosting, che prevede l'invio di 1000 email/ora, se no si finisce sul libro nero...
Pensa che ti ripensa, mi e' venuto in mente (e ho fatto qualche ricerca) che si potrebbe "accodare" messaggi in una specie di coda virtuale...sbaglio o Threading potrebbe fare al caso mio?

Questo è quel che ho partorito...ma e' abbastanza un abbozzo...
Sto cercando di crearmi una classe "SendNewsletter"...in maniera da poterla utilizzare in piu' punti del mio progetto...

public static void InviaNewsletter(string replyToMail, string msgTo, string subject, string bodyMessage)
{
  //Crea FILE di LOG con data odierna...poi lo richiamiamo nel pannello amministrativo leggendo successi e fallimenti (sarebbe il top!)
  var sendMailThread = new Thread(() =>
  {
    try
    {
      //Preparo la mail
      MailMessage msg = new MailMessage();
      msg.To.Add(msgTo);
      msg.Subject = subject;
      msg.Body = bodyMessage; //qui, creo messaggio da template e sostituisco il "cuore" del messaggio...(Ovviamente c'è un bottone per anteprima)
      msg.IsBodyHtml = true;
      msg.ReplyToList.Add(replyToMail);
      //Apro la connessione al server di posta e invio il messaggio (uno alla volta e personalizzato)
      SmtpClient smtp = new SmtpClient();
      smtp.Timeout = 10000;
      smtp.Send(msg);
      //Se tutto va bene
      //Aggiungi una righa al log e scrivi che tutto e' andato ok!
    }
    catch (Exception ex) //Se va male
    {
      //Aggiungi una righa al log e scrivi che è andata male per...indirizzo mail, nome...etc...
      //EventLog.WriteEntry("{0} Exception caught.", ex);
    }
  });
  sendMailThread.Start();
  // System.Threading.Thread.Sleep(requestTimes.Peek().Add(timeSpan).Subtract(DateTime.Now));
}



Cosa vorrei raggiungere...
Banalmente un loop che faccia si che parta una email per utente, dove il body viene personalizzato con i dati registrati (Nome, cognome, eventuale nazionalita')...e che il tutto avvenga ogni X secondi, per arrivare a mandare 500 email a ora...
O qualcosa che mi permetta di dare un invio...e ignorare l'intero processo...chiudo il tutto e il server fa il resto...
Non so se mi son spiegato...
Ne ho cercate tante, ma forse son duro di comprendonio io...e mi sto arrendendo...

Soluzioni migliori?
Procedure più...snelle?
Magari voi ne sapete piu' di me... :)
Grasssssie in anticipo :)
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
dovresti predisporre un job (anche chiamato task) da mandare in esecuzione in background, ovvero fuori dal contesto di una richiesta web.

Il codice che hai postato andrebbe a generare un nuovo thread ad ogni invio, e non risolve questi problemi:
  • Il thread parte appena invochi il metodo Start. A quel punto è inutile invocare il Thread.Sleep perché il tuo metodo InviaNewsletter genererà tanti thread che andranno in esecuzione parallelamente.
  • Non hai feedback sull'esito dell'invio. Se il Send(msg) fallisce, non avrai opportunità di ritentare con l'invio perché - di fatto - non saprai che è fallito.


Hai bisogno di pianificare un'operazione che vada in esecuzione ogni tot secondi. Ne vedi un'implementazione qui che sfrutta un timer.
http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
Sii consapevole che se la tua applicazione viene terminata da IIS per inattività, anche l'operazione verrà arrestata. Questi sono i limiti dell'hosting provider che hai scelto di usare. Se fossi stato su un server dedicato, su un VPS o su Microsoft Azure, avresti potuto creare dei servizi o dei worker che vanno in esecuzione in maniera indipendente dal sito web.

A proposito del tuo metodo InviaNewsletter: mantienilo ma riscrivilo togliendo i thread e togliendo la parte di invio della mail. Invece, il metodo dovrebbe aggiungere un record in una tabella del db, a significare che c'è una nuova email da spedire.

L'operazione pianificata andrà a fare polling su quella tabella, cioè a controllare periodicamente se sono apparse nuove email da spedire. Se ci sono, proverà a spedirle e, se l'operazione ha avuto successo, potrà marcare il record come terminato e passare così al successivo.

Nota conclusiva: tutto questo ti richiederà un bel lavoro e il risultato non potrà essere ottimale, specie se sei in regime di hosting condiviso. E' probabile che il server SMTP che ti è stato affidato abbia una reputazione media o bassa e questo è già sufficiente per far scattare alcuni filtri antispam. La tua deliverability sarà sub-standard.

Una soluzione migliore, secondo me, sarebbe quella di affidarsi ad un servizio di spedizione esterno, tipo MailChimp, che si farà carico della spedizione ai destinatari.

Come vedi dalla tabella dei prezzi, c'è un'opzione totalmente gratuita che ti permette di avere un massimo di 2.000 iscritti a cui puoi mandare 6 mail ciascuno al mese.
Puoi integrarti al servizio grazie alle sue API
http://kb.mailchimp.com/api/article/api-3-overview

Qui un'altra discussione sull'argomento.
http://forum.aspitalia.com/forum/post/396796/Invio-Multiplo-Email.aspx

ciao,
Moreno

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.