Friday, September 29, 2006

Sending Emails Asynchronously in C#

Online NewsLetters ေတြလိုမ်ိဳး၊ Email Marketing ေတြလိုမ်ိဳး၊ Email Blastering Software ေတြလိုမ်ိဳးမွာ Subscriber ေပါင္း သန္းေပါင္းမ်ားစြာကို အျမန္ဆံုးနည္းျဖင့္ တခ်ိန္တည္း တၿပိဳင္တည္း Email ပို႔တဲ့ Software တစ္ခုကို ကိုယ့္ဘာသာကို ေရးရမယ္ဆိုရင္ Asynchronous Function call ကို သံုးတာ အေကာင္းဆံုးျဖစ္ပါတယ္။  ေအာက္မွာ နဲနဲဖတ္ၾကည့္ပါ။ ကိုယ္ေတြ႔ ႀကံဳရတာေတာ့ အစက ရိုးရိုး SendMail နဲ႔ပဲ ပို႔တဲ့ C# Program က Subscriber ေပါင္း ႏွစ္ေသာင္း အတြက္ မိနစ္ ႏွစ္ဆယ္ခန္႔ေလာက္ ၾကာပါတယ္။ ဒါနဲ႔ ဒီ Asynchronous နည္း ကိုေျပာင္းသံုးလိုက္တာ Subscriber ႏွစ္ေသာင္းအတြက္ 3 စကၠန္႔ေလာက္ပဲ ၾကာပါေတာ့တယ္။

So we start out with some handy properties (SmtpServer, etc.) which can be set on the class prior to calling any methods, for convenience purposes. Then we have our SendEmail method, which looks like any normal synchronous method - no difference at all.

Now comes the interesting stuff: First, we need a delegate:

public delegate string SendEmailDelegate(string name, string emailAddress);

Then finally we need the callback method:

public void GetResultsOnCallback(IAsyncResult ar)
{
SendEmailDelegate del = (SendEmailDelegate) ((AsyncResult)ar).AsyncDelegate;
string result;
result = del.EndInvoke(ar);
}

Notice the delegate must have the same signature as the method. Based on this delegate syntax, we can now call the BeginInvoke() and EndInvoke() methods:


public string SendEmailAsync(string name,string emailAddress)
{
SendEmailDelegate dc = new SendEmailDelegate(this.SendEmail);
AsyncCallback cb = new AsyncCallback(this.GetResultsOnCallback);
IAsyncResult ar = dc.BeginInvoke(name,emailAddress, cb, null);
return "ok";
}

Note that the delegate calls BeginInvoke / EndInvoke use a Framework – managed ThreadPool under the hood--
so you don’t get 4,000 runaway threads. When a thread completes, it is automatically made available to be re-used for the next BeginInvoke call in your loop. So your default ThreadPool size of 25 threads is as high as you get. You could experminent with different ThreadPool sizes, but the main thing is you want to avoid just creating thousands of threads, one for each email, and having your box crash under the load.

Detail:
Sending Emails Asynchronously in C#
By Peter A. Bromberg, Ph.D.
Printer - Friendly Version

2 comments:

Unknown said...

Sound good. I will try it when I got free time.
Thanks again.

Philip Shield said...

It may be useful in CRM applications, such as lead generations.