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

私はこのコードを持っていますが、メールを非同期で送信できるように改善したいと思います。このコードを改善するためのアイデアや、それを行うための他の方法を提案していただけますか。Visual Studioが提案した非同期プロパティを試しましたが、使用できませんでした。

4

3 に答える 3

11

SmtpClient非同期で送信でき、イベントを使用して送信が完了したときに通知します。これは使いにくい場合があるため、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
    }
});
于 2013-02-28T16:24:56.523 に答える
1

ワイルドな推測ですが、SendAsyncがその仕事をするかもしれません!

于 2013-02-28T16:19:47.303 に答える
0

次のコードを変更します。

 client.Send(msg);

に:

client.SendAsync(msg);

詳細

link1

link2

于 2013-02-28T16:20:26.183 に答える