Send async e-mails

前端 未结 4 1186
一整个雨季
一整个雨季 2020-12-09 19:53

I am using ASP.NET MVC 3 with MVCMailer, I tried to send e-mails using SendAsync, but actually it still take longer.

So I am trying to use Task.Factory like the code

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-09 20:43

    Task.Factory.StartNew will create a new thread.
    If you want to access HttpContext which is in the main thread you have to do this:

    var task1 = Task.Factory.StartNew(() =>
        {
        System.Web.HttpContext.Current = ControllerContext.HttpContext.ApplicationInstance.Context;
        var mail = new UserMailer();
        var msg = mail.Welcome("My Name", "myemail@gmail.com");
        msg.SendAsync();
        });
    
    task1.Wait();
    

    There a long debate if it's better to use TPL or QueueUserWorkItem.
    Someone has tried to address the issue.
    This is the QueueUserWorkItem version:

    public class HomeController : Controller
    {
        private AutoResetEvent s_reset = new AutoResetEvent(false);
    
        public ActionResult Index()
        {
            var state = new WorkerState() { HttpContextReference = System.Web.HttpContext.Current };
            ThreadPool.QueueUserWorkItem(new WaitCallback(EmaiSenderWorker), state);
    
            try
            {
            s_reset.WaitOne();
            }
            finally
            {
            s_reset.Close();
            }
    
            return View();
        }
    
        void EmaiSenderWorker(object state)
        {
            var mystate = state as WorkerState;
    
            if (mystate != null && mystate.HttpContextReference != null)
            {
            System.Web.HttpContext.Current = mystate.HttpContextReference;
            }
    
            var mail = new UserMailer();
            var msg = mail.Welcome();
            msg.SendAsync();
    
            s_reset.Set();
        }
    
        private class WorkerState
        {
            public HttpContext HttpContextReference { get; set; }
        }
    
    }
    

提交回复
热议问题