2013-02-28 77 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