2016-05-23 66 views
1

我需要发送大约5000封电子邮件作为我的网站用户的电子邮件异步..问题是我不知道最好的方式发送它们异步..请帮我更新我的代码,使其异步如何在ASP.NET中异步发送通讯(批量电子邮件)

我的代码:

public string SendEmail() 
    { 


     foreach (var emailAddress in EmailList) 

     { 
      var message = new MailMessage("[email protected]", emailAddress); 

      message.Subject = "hi"; 
      SmtpClient client = new SmtpClient("smtp.gmail.com", 587); 
      client.Credentials = new NetworkCredential("[email protected]", "*****"); 
      client.EnableSsl = true; 
      client.Send(message); 
     } 
     return "done"; 
    } 

谢谢,露西

+0

由于[THIS](https://msdn.microsoft.com/de-de/library/x5x13z6h(v = vs.110).aspx)应该有一个异步函数文章 – Marius

+1

1)创建窗口服务器 2)安排它在2分钟内执行 3)为每封电子邮件创建线程。 这样你可以异步发送电子邮件。 –

+0

在操作方法中使用异步/等待仍然强制用户等待一切完成。您可以使用单一线程以“即燃即用”方式在后台执行所有处理,而用户可以执行其他操作(即使离开您的网站或关闭浏览器)。 –

回答

2

看看asyncawait关键字。

https://msdn.microsoft.com/en-us/library/mt674882.aspx

异步和等待关键字在C#中的异步编程的心脏。通过使用这两个关键字,您可以使用.NET Framework或Windows运行时中的资源创建一个异步方法,就像创建同步方法一样容易。通过使用async和await定义的异步方法称为异步方法。

MSDN解释事物的语法方面。更大的担忧是错误处理和可靠。将5000封电子邮件转储到列表中,然后点击“发送”按钮有点乐观。这些电子邮件是否需要可靠地交付?如果发送其中的3000个,会发生什么情况,并且网络错误突然导致传出邮件服务器暂时失去连接?当它重新开始工作时,你是否会重新发送所有5,000个?忘记过去的2000年?收件人是否会因为重复而发疯?或者根本没有收到邮件?你如何解决错误?

我发现已经真的很好的模式(无论您是同步或异步发送),是产生信息和每个存储在数据库中的表,然后使用类似以下内容:

public void SendAllEmails() 
{ 
    var emails = SomeClass.GetAllUnsentEmails(); 

    foreach(Email message in Emails) 
    { 
     var success = SendEmail(message); 

     if (!success) 
     { 
      // Do you want to do something if it fails? 
     } 
    } 
} 

public bool SendEmail(Email message) 
{ 
    try 
    { 
     // 1. Send the email message 
     // 2. Update the "SentOn" date in the database 
     // 3. return true 
    } 
    catch(Exception ex) 
    { 
     SomeClass.CreateEmailErrorEntry(message, ex); // store error in a table or log 
     return false; 
    } 
} 
0

编辑:如果它正在采取行动的内部使用,你应该标记你的动作异步

public async Task<ActionResult> MyAction() 

一开始,没有为每个消息创建SmtpClient所以如下 也是这样,应该异步发送的电子邮件,但等待他们全部被送到

public string SendEmail() 
    { 
     var tasks = new List<Task>(); 
     var client = new SmtpClient("smtp.gmail.com", 587); 
     client.Credentials = new NetworkCredential("[email protected]", "*****"); 
     client.EnableSsl = true; 
     foreach (var emailAddress in EmailList) 
     { 
      var message = new MailMessage("[email protected]", emailAddress); 
      message.Subject = "hi"; 
      tasks.Add(client.SendMailAsync(message)); 
     } 
     while(tasks.Count > 0) 
     { 
      var idx = Task.WaitAny(tasks.ToArray()); 
      tasks.RemoveAt(idx); 
     } 
     return "done"; 
    } 
+0

感谢您的帮助和时间....对于tasks.Add(client.SendAsync(message));它说参数1:不能从'void'转换为'System.Threading.Tasks。任务' – Lucia

+0

@Lucia修复了不正确的方法 – elibyy

+0

如果您想在退出while循环之前等待所有任务完成,您可能需要更改为WaitAll。 – Asdfg