开发者

SendEmail method not working

I'm writing an application which sends a lot of emails throughout the app's lifecycle.

The users complained that the application was really unresponsive and generally slow. The only thing I could come up with as the reason, was the heavy email sending. So I thought I could solve the problem by sending the emails in a different thread!

I'm using the SendEmail method in the SPUtility helper class. Right now, I have a method that looks like this:

public static void SendEmail(SPWeb web, string to, string subject, string body)
{

    //Some logic goes here
    System.Threading.ThreadPool.QueueUserWorkItem(o =>
    {
        SPUtility.SendEmail(web, false, false, to, subject, body, false);
    });
}

This method is defined in a DLL, and it's being called from a LOT of different webparts.

But this is not working. If I remove the QueueUserWorkItem bit, and ju开发者_运维技巧st let it send emails outside of a thread, it works like a charm, but then again, it's slow.

How can I solve this?


I suspect you're better off using MailMessage Class (System.Net.Mail)

MailMessage mess = 
    new MailMessage(
        SPContext.Current.Site.WebApplication.OutboundMailReplyToAddress, 
        sendTo, 
        subject, 
        message);  
mess.IsBodyHtml = true;  
SmtpClient smtp = 
    new SmtpClient(
        SPContext.Current.Site.WebApplication.OutboundMailServiceInstance.Server.Address);  
smtp.Send(mess);

this MSDN post is similar to your situation, Sending Email using SPUtility.SendEmail slow in production


Also there is an option to do something like this:

public static void SendEmail(SPWeb web, string to, string subject, string body)
{
    var siteId = Web.Site.ID;

    System.Threading.ThreadPool.QueueUserWorkItem(o =>
    {
        using (var site = new SPSite(siteId))
        using (var myWeb = site.OpenWeb())
        {
            SPUtility.SendEmail(myWeb, false, false, to, subject, body);
        }
    });
}

Maybe it will be interesting to someone.


You should consider a more distributed pattern for sending these emails. Specifically, I would define some structure to store "send requests". This can be a SharePoint List, a MSMQ, a Queue in Azure Storage, etc.

Your send email method would enqueue a request in this storage unit and you would have a separate process or processes poll that queue to check for new requests periodically. When new items are found they will be executed and dequeued.

if you chose to use multiple agents to process these requests, you may need to defined a more complex mechanism orchestrating these agents to prevent interference.

As for the host for the agent(s), this can be an app that is registered as a Scheduled Task, a Windows Service with a "Timer", or a SharePoint Workflow that is invoke my the Timer.

This is just one implementation, but ultimately you want to decouple the action of "requesting" the email send from the act of "executing" that email send.


A quick fix until you can setup a more permanent solution would be to send your emails to an smtp server on the same machine and have it relay them for you.

Down the road I would create an email service and that is easy to call like a wcf service, which you can incorporate threading into.


Are you getting any error message? I ran into this once and ended up putting a small delay (ex. Thread.Sleep(500)) before sending out each email. For some reason, the smtp server rejected some of the emails that were sent. In addition, you should follow @rushonerok's advice and send email via SMTP server instead. GlennFerrieLive is a much more robust solution and should looked at as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜