Introduction

I was working on web application; one of the requirements was to send the bulk mails to multiple users.

Earlier, I was using SMTP client object to send the mail. But when the number of recipient increases, application stuck for long time. Also Same SMTP server was used among multiple applications, so load on Server was very high.
For performance optimization, I have created new queue using MSMQ on separate server where all the mails are queued and then created one application which will read emails one by one and send it via SMTP client. Now my original web application is not directly connecting to SMTP server, due to which wait time for sending bulk mail will be very low and load on SMTP server will be less.

Background

MSMQ is essentially a messaging protocol that allows applications running on separate servers or processes(s) to communicate in a failsafe manner. A queue is a temporary storage location from which messages can be sent and received reliably. They can be used for communication across heterogeneous networks and between computers which may not always be connected. Steps to create MSMQ – Queue manually are as follows:

1 Right click on “My Computer”. 2 Click on “Manage”. 3 Expand Services And Application. 4 Now you can see the “Message Queuing”. 5 Expand “Private Queue”, click on “New Private queue” – Enter the name “emailqueue”.

This will create new Queue, please refer the attached document for details. Now we will see how to create it using programmatically.
Please note: Name spaces required are: ‘System.Messaging’ - for MSMQ and ‘System.Net.Mail ‘- for sending mail using SMTP client. Also MSMQ must be installed on your machine.

Using the code

Now we will see how to use MSMQ to send mail programmatically. I have divided application in two parts:

1. Application which will create MSMQ queue and hold all mail - information as an object.
2. Application which will read mail info from Queue and send email via SMTP.
Part 1:

First we will look into Email Sender part: Here, I have created Windows form which will take inputs from user like “To Address”, “From Address”,”Subject”,”Body” etc. On the “Send Button” click, call method” QueueMessage “from “EmailService”.

QueueMessage : is used to create the transactional Queue, if it does not exist also pushes the data inside this queue.

string msmqQueuePath = @".\Private$\EmailQueue";
// Create new instance of Message object

   Message msmqMsg = new Message();

// Assign email information to the Message body

                msmqMsg.Body = emailMessage;
//set Recoverable which indicates message is garunteed 
                msmqMsg.Recoverable = true;
//Set Formatter to serilize the object,I’m using binary //serilization
                msmqMsg.Formatter = new BinaryMessageFormatter();
//Create message queue instance 
                MessageQueue msmqQueue = new MessageQueue();
                //If the Message queue does not exists at specified 
//location create it

                if (!MessageQueue.Exists(msmqQueuePath))
                {
                   msmqQueue =  MessageQueue.Create(msmqQueuePath);
                }
 
//  Set Formatter to serilize the object. 

                msmqQueue.Formatter = new BinaryMessageFormatter();

//Send the message object in the created queue

                msmqQueue.Send(msmqMsg);
		

Part2:

Email Receiver :
Here, I have created console application, which will be running continiously to read any new message.

We need instance of message queue, which will read the email message object from specifed path.please note, Message path in receiver must be same as sender.Then raise receive complete even of message queue.

Like: _msmqQueue.ReceiveCompleted+= In msmqQueue_ReceiveCompleted event : extract the actual message like: (EmailEntities.EmailMessage)e.Message.Body.

Now create the instance of “MailMessage” and set the appropriate properties. Create instance of SMTP client and call Send method This will send the actual message from the queue.

//message path must be same as sender
string messageQueuePath = @".\private$\EmailQueue";
//create message queue instance
                    _msmqQueue = new MessageQueue(messageQueuePath);
//set formatter same as sender
                    _msmqQueue.Formatter =  new BinaryMessageFormatter();
                    _msmqQueue.MessageReadPropertyFilter.SetAll();
//Raise receive completed event 
_msmqQueue.ReceiveCompleted+=new ReceiveCompletedEventHandler(msmqQueue_ReceiveCompleted);
//start receiving messages
                    _msmqQueue.BeginReceive();
//In msmqQueue_ReceiveCompleted
//Extract the actual message 
EmailEntities.EmailMessage emailMsg = (EmailEntities.EmailMessage)e.Message.Body;
//Create mail message instance 
MailMessage mailMesage = new MailMessage();
//Set the properties
mailMesage.Subject = emailMsg.Subject;
mailMesage.Body = emailMsg.Body;
//Create Smtp client instance
SmtpClient oclient = new SmtpClient();
//call the send method 
oclient.Send(mailMesage);

Points of Interest

For more information Refer: http://msdn.microsoft.com/en-us/library/ms978430.aspx

History

Inital Version

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"