2012-08-30 19 views
10

मैं एमवीसीमेलर के साथ एएसपी.नेट एमवीसी 3 का उपयोग कर रहा हूं, मैंने SendAsync का उपयोग करके ई-मेल भेजने की कोशिश की, लेकिन वास्तव में यह अभी भी अधिक समय लेता है। MVCMailer जरूरत HttpContextasync ई-मेल भेजें

var task1 = Task.Factory.StartNew(
      state => 
      { 
       var mail = new UserMailer(); 
       var msg = mail.Welcome("My Name", "[email protected]"); 
       msg.SendAsync(); 
      }); 

    task1.Wait(); 

समस्या है, है, लेकिन इस कार्य के अंदर मुझे मिल गया HttpContext अशक्त:

तो मैं कोड bellow तरह Task.Factory उपयोग करने के लिए कोशिश कर रहा हूँ।

मैं Async ई-मेल कैसे भेज सकता हूं?

उत्तर

18

यह करने के लिए एक छोटा सा अतिरिक्त:
यह QueueUserWorkItem संस्करण है। कुछ की मदद करने के लिए यहां एक विस्तार विधि है।

using Mvc.Mailer; 
using System.Threading.Tasks; 
public static void SendEmailAsync(this MvcMailMessage msg, HttpContext currContext) 
{ 
     //make this process a little cleaner 
     Task.Factory.StartNew(() => 
     { 
      System.Web.HttpContext.Current = currContext; 
      msg.SendAsync(); 
     }); 
} 

इसे अपने नियंत्रक विधियों से निम्न प्रकारों का उपयोग करें।

Mailers.UserMailer um = new Mailers.UserMailer(); 
um.SendWelcomeEmail(dataObject).SendEmailAsync(ControllerContext.HttpContext.ApplicationInstance.Context); 
+0

हे मैट! संदर्भ के लिए धन्यवाद, यह बहुत अच्छा लग रहा है, क्या यह इसे असीमित रूप से 100% भेजता है, मैंने सुना है कि लोगों ने कहा है कि एमवीसीमेलर एक छद्म एसिंक हाहा था। धन्यवाद दोस्त! – Baconbeastnz

+2

कोई जांच नहीं! मैं इस के साथ डेस्क के खिलाफ अपने सिर को टक्कर लगी थी :) – Matt

+0

@ मैट, यह बहुत अच्छा काम करता है !!! धन्यवाद!!! =) –

0

आपको कार्यों की आवश्यकता नहीं है। SendAsync असीमित है और एक और थ्रेड स्वयं का उपयोग करें। कार्य आपको मेलिंग में तेजी नहीं देते हैं।

अद्यतन: जब मैं एक ही समस्या का समाधान करता हूं तो मैं कार्य और सिंक्रोनस भेजता हूं। ऐसा लगता है कि SendAsync इतना असंतुष्ट नहीं था। यह मेरी कोड का नमूना है (यह HttpContext नहीं चाहता है):

public void SendMailCollection(IEnumerable<Tuple<string, string, MailAddress>> mailParams) 
    { 
     var smtpClient = new SmtpClient 
     { 
      Credentials = new NetworkCredential(_configurationService.SmtpUser, _configurationService.SmtpPassword), 
      Host = _configurationService.SmtpHost, 
      Port = _configurationService.SmtpPort.Value 
     }; 

     var task = new Task(() => 
           { 
            foreach (MailMessage message in mailParams.Select(FormMessage)) 
            { 
             smtpClient.Send(message); 
            } 

           }); 
     task.Start(); 
    } 

    private MailMessage FormMessage(Tuple<string, string, MailAddress> firstMail) 
    { 
     var message = new MailMessage 
      { 
       From = new MailAddress(_configurationService.SmtpSenderEmail, _configurationService.SmtpSenderName), 
       Subject = firstMail.Item1, 
       Body = firstMail.Item2 
      }; 
     message.To.Add(firstMail.Item3); 
     return message; 
    } 
+0

किरील, इसमें अधिक समय क्यों लगता है? मुझे पृष्ठभूमि में ई-मेल भेजने की ज़रूरत है। –

+0

असिंक्रोनस का मतलब तेज़ नहीं है। इसका मतलब है कि आपकी धीमी प्रक्रिया आपके बेस थ्रेड को अवरुद्ध नहीं करेगी और आपका एप्लिकेशन उपयोगकर्ता क्रियाओं पर प्रतिक्रिया करेगा –

+0

निश्चित रूप से, लेकिन जब मैं ईमेल भेजता हूं, तो प्रक्रिया इस कार्य से अवरुद्ध होती है। –

4

Task.Factory.StartNew एक नया धागा पैदा करेगा।
आप आप ऐसा करते हैं करने के लिए है HttpContext जो मुख्य थ्रेड में है का उपयोग करना चाहते हैं:

var task1 = Task.Factory.StartNew(() => 
    { 
    System.Web.HttpContext.Current = ControllerContext.HttpContext.ApplicationInstance.Context; 
    var mail = new UserMailer(); 
    var msg = mail.Welcome("My Name", "[email protected]"); 
    msg.SendAsync(); 
    }); 

task1.Wait(); 

वहाँ एक लंबी बहस अगर यह TPL या QueueUserWorkItem उपयोग करने के लिए बेहतर है।
किसी ने issue को संबोधित करने का प्रयास किया है।

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; } 
    } 

} 
+0

हाँ LeflyX! मैंने पहले ही यह कोशिश की है, लेकिन मुझे नहीं पता कि संदर्भ चर को MVCMailer ऑब्जेक्ट में पास करना संभव है या नहीं। –

+1

@ मिशेल एंड्रैड: मैंने अपना जवाब अपडेट कर दिया है। यह देखने की कोशिश करें कि यह मदद करता है या नहीं। – LeftyX

+0

लेफ्लेक्स, लगभग वहां, अगर मैं "task1.Wait();" यह –

0
public class UserMailer : MailerBase  
{ 
    RegisterService Service = new RegisterService(); 
    HttpContext Context; 
    public UserMailer(HttpContext context) 
    { 
     Context = context; 
     MasterName="_Layout"; 
    } 

    public void ConfirmRegistration(Register model) 
    { 
     SendAsync(() => 
     { 
      model.Conference = Service.Context.Conferences.Find(model.ConferenceID); // load conference bcs it fails to lazy load automatically. 
      ViewData.Model = model; 
      return Populate(x => 
      { 
       x.Subject = "You registered for " + model.Conference.Name + "!"; ; 
       x.ViewName = "Confirm"; 
       x.To.Add(model.Email); 
      }); 
     }); 
    } 

    private void SendAsync(Func<MvcMailMessage> GetEmail) 
    { 
     Task.Factory.StartNew(() => 
     { 
      System.Web.HttpContext.Current = Context; 
      GetEmail().Send(); 
     }); 
    } 
+2

उत्तर पोस्ट करने के लिए धन्यवाद! जबकि एक कोड स्निपेट सवाल का जवाब दे सकता है, लेकिन अभी भी कुछ अतिरिक्त जानकारी, जैसे व्याख्या, आदि जोड़ना बहुत अच्छा है .. – j0k

संबंधित मुद्दे