2013-02-28 76 views
0
namespace Binarios.admin 
{ 
    public class SendEmailGeral 
    { 
     public SmtpClient client = new SmtpClient("smtp.gmail.com", 587); 
     public MailMessage msg = new MailMessage(); 

     public void Enviar(string sendFrom, string sendTo, string subject, string body) 
     {  
      string pass = "12345"; 
      System.Net.NetworkCredential smtpCreds = new System.Net.NetworkCredential(sendFrom, pass); 

      //setup SMTP Host Here 
      client.UseDefaultCredentials = false; 
      client.Credentials = smtpCreds; 
      client.EnableSsl = true; 

      MailAddress to = new MailAddress(sendTo); 
      MailAddress from = new MailAddress(sendFrom); 

      msg.IsBodyHtml = true; 
      msg.Subject = subject; 
      msg.Body = body; 
      msg.From = from; 
      msg.To.Add(to); 

      client.Send(msg); 
     } 
    } 
} 

我有这段代码,但我想改进它的方式,我可以发送邮件异步。 你能否提出任何想法来改进这段代码或其他方式来做到这一点。 我试过视觉工作室建议但不能使用它们的异步属性。如何发送邮件异步?

+2

你有没有实际看在文档中? http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx – Arran 2013-02-28 16:17:16

+0

尝试搜索之前??? [在C#中异步发送电子邮件?](http://stackoverflow.com/questions/3408397/asynchronously-sending-emails-in-c).. [通过SmtpClient异步发送电子邮件的两种方式](http:// stackoverflow。 com/questions/8768863/two-way-to-send-email-via-smtpclient-asynchronously-different-results) – 2013-02-28 16:20:29

回答

11

SmtpClient允许您异步发送,并使用事件在发送完成时通知您。这可能是unweildy使用,这样你就可以创建一个扩展方法返回一个Task来代替:

public static Task SendAsync(this SmtpClient client, MailMessage message) 
{ 
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); 
    Guid sendGuid = Guid.NewGuid(); 

    SendCompletedEventHandler handler = null; 
    handler = (o, ea) => 
    { 
     if (ea.UserState is Guid && ((Guid)ea.UserState) == sendGuid) 
     { 
      client.SendCompleted -= handler; 
      if (ea.Cancelled) 
      { 
       tcs.SetCanceled(); 
      } 
      else if (ea.Error != null) 
      { 
       tcs.SetException(ea.Error); 
      } 
      else 
      { 
       tcs.SetResult(null); 
      } 
     } 
    }; 

    client.SendCompleted += handler; 
    client.SendAsync(message, sendGuid); 
    return tcs.Task; 
} 

为了得到发送任务的结果,你可以使用ContinueWith

Task sendTask = client.SendAsync(message); 
sendTask.ContinueWith(task => { 
    if(task.IsFaulted) { 
     Exception ex = task.InnerExceptions.First(); 
     //handle error 
    } 
    else if(task.IsCanceled) { 
     //handle cancellation 
    } 
    else { 
     //task completed successfully 
    } 
}); 
+0

这现在给我一个错误,它说:发送邮件失败。 – Severiano 2013-02-28 17:03:42

+0

@DiogoSeveriano - 首先,我最初发布的代码中存在一个会导致堆栈溢出异常的错误。如果您使用的是当前版本的代码,则应该能够在任务完成时从该任务中获取内部异常。什么是例外? – Lee 2013-02-28 17:06:06

+0

我解决了页面中Async =“true”的问题,这是问题,但现在我认为这不会发送异步,因为我仍然必须等待这个发送邮件,然后我可以做一些事情。 – Severiano 2013-02-28 17:12:41

0

更改代码:

client.Send(msg); 

要:

client.SendAsync(msg); 

详情

link1

link2

+0

发送邮件失败。当使用它。 – Severiano 2013-02-28 16:23:17

+4

@DiogoSeveriano,好吧*它*失败了吗?任何错误?它是否默默地失败?你的电脑是否着火? **如何**这不起作用? – Arran 2013-02-28 16:24:42