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

+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-асинхронно-разные результаты) –

ответ

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

+0

@DiogoSeveriano - Во-первых, в исходном коде, который я изначально опубликовал, произошла ошибка, которая вызвала бы исключение переполнения стека. Если вы используете текущую версию кода, вы сможете получить внутреннее исключение из задачи при ее завершении. Какое исключение? – Lee

+0

Я решил проблему с Async = "true" на странице, это была проблема, но теперь я думаю, что это не отправляет асинхронный, потому что мне все еще нужно подождать, чтобы отправить почту, а затем я могу что-то сделать. – Severiano

0

Изменить код из:

client.Send(msg); 

To:

client.SendAsync(msg); 

более подробной

link1

link2

+0

Неисправность отправки почты. при использовании этого. – Severiano

+4

@DiogoSeveriano, хорошо * как * это не удается? Любые ошибки? Это тихо проваливается? Ваш компьютер загорается? ** Как ** это не работает? – Arran