Skicka mail i en egen tråd

by Reager 5. July 2009 21:11

Ofta på våra webbplatser så vill vi skicka ut mail till våra användare, men vi vill inte sitta och vänta tills alla är skickade och sidan laddas om. Vad gör vi då? En lösning är att skicka
mailen i en egen tråd. Detta gör att mailutskicket hanteras i en egen tråd på servern och vi kan fortsätta surfa och låta mailutskicket sköta sig självt.

Att åstakomma detta är mycket enklare än vad man kan tro. Jag kommer i detta exempel att ha mina medlemmar som jag vill skicka mail till i ett xml-ark, men detta kan
givetvis anpassas så att du hämtar din information från databasen istället.

Det första jag gör är att skapa en ny webbplats i visual studio. Sedan skapar jag en xml-fil i mappen App_Data med en root-nod users, samt några user-element som innehåller namn samt epost-adress.

XML-filen ser ut på följande vis

<?xml version="1.0" encoding="utf-8" ?>
<users>
  <user>
    <name>
      Daniel      
    </name>
    <email>
      test@aspdotnet.nu      
    </email>
  </user>

  <user>
    <name>
      Kalle
    </name>
    <email>
      test1@aspdotnet.nu
    </email>
  </user>
</users>

I default.aspx som VS har skapat åt oss så drar vi ut två textboxar samt en knapp. Den ena textboxen ska vara "Multiline" och innehålla vårat mail och den andra ska innehålla vårat ämne för mailen. Knappen ska vi ha för att skicka mailet. Sätt lämpliga ID:n på alla tre element samt text och ett klick-event på knappen. Din kod bör se ut något i stil med

<asp:TextBox ID="Subject" runat="server"></asp:TextBox>
<asp:TextBox ID="Body" TextMode="MultiLine" runat="server"></asp:TextBox>
<asp:Button ID="SendMail" runat="server" Text="Skicka mail" OnClick="SendMail_Click"/>

För event så använder jag namnkonventionen elementID_event, men du kan namnge det hur du vill. När detta är klart går vi över till kodläget. Börja med att inkludera följande tre "namnrymderna".

using System.Net.Mail;
using System.Threading;
using System.Xml;

Nästa steg är att skapa själva klick-eventet för knappen samt koden som startar tråden.

protected void SendMail_Click(object sender, EventArgs e)
{
    // Det enda vi ska göra här är att säga åt programmet att vi
    // vill köra en metod i en egen tråd och det gör man genom följande rad. 
// Det vi skickar med är ämnet och meddelandet och delar det med | så att vi kan
// splitta det i tråden sen då det bara går att skicka med ett objekt. ThreadPool.QueueUserWorkItem(new WaitCallback(SendMailInThread),
Subject.Text + "|" + Body.Text); }

Som du ser skickar vi in ett objekt av typen WaitCallback med vårat metodnamn som argument till metoden QueueUserWorkItem. Det är i denna metod SendMailInThread som allt arbete kommer att ske. För att skicka själva mailen så måste vi givetvis skapa denna metod, och den ser ut på följande vis:

private void SendMailInThread(object o)
{
        // Vi skapar ett xdoc och laddar in våran xml-fil i denna
        XmlDocument xdoc = new XmlDocument();
        xdoc.Load(Server.MapPath("") + @"\App_Data\users.xml");
        // Sedan hämtar vi ut alla user-noder i vårat xmldoc med
        // hjälp av xpath
        XmlNodeList xlist = xdoc.SelectNodes("users/user");
        // Denna nodelist kommer att innehålla elementen som finns i user-elementen
        XmlNodeList xlistChildren;


        // Här har vi våra mail-inställningar
        string[] subbody = ((string)o).Split(new char[] { '|' });
        SmtpClient smtp = new SmtpClient("smtp.bahnhof.se");
        MailMessage mess = new MailMessage();
        mess.From = new MailAddress("info@aspdotnet.nu", "Webbmaster");
        mess.Subject = subbody[0];
        mess.Body = subbody[1];

        // Sedan loopar vi igen dem och hämtar våra element med namn 
        // samt epost samt skickar mail
        for (int i = 0; i < xlist.Count; i++)
        {
            xlistChildren = xlist[i].ChildNodes;
            // Först anger vi vem mailet ska till. Vi använder Trim() för att 
// vara säkra på att inga blanksteg åker med mess.To.Add(new MailAddress(xlistChildren[1].InnerText.Trim(),
xlistChildren[0].InnerText.Trim())); // Här skickar vi vårat mail smtp.Send(mess); // Då vi la till adressen till en collection så måste vi tömma
// denna så inte ovanstående person får mailet flera gånger mess.To.Clear(); } }

Det var det hela, jag hoppas du har fått ut något av denna lilla artikel. Om du vill kan du ladda hem den här: MailThread.zip (5,02 kb)

Tags:

Comments

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentComments

Comment RSS