代码之家  ›  专栏  ›  技术社区  ›  Eton B.

异步发送C#格式的电子邮件?

  •  34
  • Eton B.  · 技术社区  · 14 年前

    我正在开发一个应用程序,在这个应用程序中,用户单击/按下窗口中某个按钮的enter键,该应用程序会进行一些检查,并确定是否要发送几封电子邮件,然后显示另一个带有消息的窗口。

    有没有办法让我把这些邮件放在后台,然后马上显示下一个窗口?

    请不要用“使用X类”或“只使用X方法”来限制您的回答,因为我还不太熟悉这门语言,如果您能提供更多信息,我们将不胜感激。

    谢谢。

    10 回复  |  直到 14 年前
        1
  •  77
  •   Boris Lipschitz    11 年前

    从.NET 4.5开始,SmtpClient实现异步等待方法 SendMailAsync 因此,异步发送电子邮件的步骤如下:

    public async Task SendEmail(string toEmailAddress, string emailSubject, string emailMessage)
    {
        var message = new MailMessage();
        message.To.Add(toEmailAddress);
    
        message.Subject = emailSubject;
        message.Body = emailMessage;
    
        using (var smtpClient = new SmtpClient())
        {
            await smtpClient.SendMailAsync(message);
        }
    } 
    
        2
  •  26
  •   James    14 年前

    ThreadPool.QueueUserWorkItem 在线程方面。如果你使用 SmtpClient 类来发送您的邮件,您可以处理 SendCompleted 事件以向用户提供反馈。

    ThreadPool.QueueUserWorkItem(t =>
    {
        SmtpClient client = new SmtpClient("MyMailServer");
        MailAddress from = new MailAddress("me@mydomain.com", "My Name", System.Text.Encoding.UTF8);
        MailAddress to = new MailAddress("someone@theirdomain.com");
        MailMessage message = new MailMessage(from, to);
        message.Body = "The message I want to send.";
        message.BodyEncoding =  System.Text.Encoding.UTF8;
        message.Subject = "The subject of the email";
        message.SubjectEncoding = System.Text.Encoding.UTF8;
        // Set the method that is called back when the send operation ends.
        client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
        // The userState can be any object that allows your callback 
        // method to identify this send operation.
        // For this example, I am passing the message itself
        client.SendAsync(message, message);
    });
    
    private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
            // Get the message we sent
            MailMessage msg = (MailMessage)e.UserState;
    
            if (e.Cancelled)
            {
                // prompt user with "send cancelled" message 
            }
            if (e.Error != null)
            {
                // prompt user with error message 
            }
            else
            {
                // prompt user with message sent!
                // as we have the message object we can also display who the message
                // was sent to etc 
            }
    
            // finally dispose of the message
            if (msg != null)
                msg.Dispose();
    }
    

        3
  •  13
  •   EvilDr    5 年前

    using System.Net.Mail;
    
    Smtp.SendAsync(message);
    

    或者,如果您希望在单独的线程上构造整个消息,而不只是异步发送:

    using System.Threading;
    using System.Net.Mail;
    
    var sendMailThread = new Thread(() => {
        var message=new MailMessage();
        message.From="from e-mail";
        message.To="to e-mail";
        message.Subject="Message Subject";
        message.Body="Message Body";
    
        SmtpMail.SmtpServer="SMTP Server Address";
        SmtpMail.Send(message);
    });
    
    sendMailThread.Start();
    
        4
  •  8
  •   Kiquenet user385990    11 年前

    SmtpClient.SendAsync Method

    样品

    using System;
    using System.Net;
    using System.Net.Mail;
    using System.Net.Mime;
    using System.Threading;
    using System.ComponentModel;
    namespace Examples.SmptExamples.Async
    {
        public class SimpleAsynchronousExample
        {
            static bool mailSent = false;
            private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
            {
                // Get the unique identifier for this asynchronous operation.
                 String token = (string) e.UserState;
    
                if (e.Cancelled)
                {
                     Console.WriteLine("[{0}] Send canceled.", token);
                }
                if (e.Error != null)
                {
                     Console.WriteLine("[{0}] {1}", token, e.Error.ToString());
                } else
                {
                    Console.WriteLine("Message sent.");
                }
                mailSent = true;
            }
            public static void Main(string[] args)
            {
                // Command line argument must the the SMTP host.
                SmtpClient client = new SmtpClient(args[0]);
                // Specify the e-mail sender. 
                // Create a mailing address that includes a UTF8 character 
                // in the display name.
                MailAddress from = new MailAddress("jane@contoso.com", 
                   "Jane " + (char)0xD8+ " Clayton", 
                System.Text.Encoding.UTF8);
                // Set destinations for the e-mail message.
                MailAddress to = new MailAddress("ben@contoso.com");
                // Specify the message content.
                MailMessage message = new MailMessage(from, to);
                message.Body = "This is a test e-mail message sent by an application. ";
                // Include some non-ASCII characters in body and subject. 
                string someArrows = new string(new char[] {'\u2190', '\u2191', '\u2192', '\u2193'});
                message.Body += Environment.NewLine + someArrows;
                message.BodyEncoding =  System.Text.Encoding.UTF8;
                message.Subject = "test message 1" + someArrows;
                message.SubjectEncoding = System.Text.Encoding.UTF8;
                // Set the method that is called back when the send operation ends.
                client.SendCompleted += new 
                SendCompletedEventHandler(SendCompletedCallback);
                // The userState can be any object that allows your callback  
                // method to identify this send operation. 
                // For this example, the userToken is a string constant. 
                string userState = "test message1";
                client.SendAsync(message, userState);
                Console.WriteLine("Sending message... press c to cancel mail. Press any other key to exit.");
                string answer = Console.ReadLine();
                // If the user canceled the send, and mail hasn't been sent yet, 
                // then cancel the pending operation. 
                if (answer.StartsWith("c") && mailSent == false)
                {
                    client.SendAsyncCancel();
                }
                // Clean up.
                message.Dispose();
                Console.WriteLine("Goodbye.");
            }
        }
    }
    
        5
  •  6
  •   fdfrye    14 年前

    在c#/.net等中,有很多方法可以实现异步或并行工作。

    关于后台工作线程的提示:您不能直接从它们更新UI(线程关联和封送只是您学习处理的一些东西…)

    另一件需要考虑的事情……如果你使用标准St.Ne.mail类型的邮件发送邮件……小心你的逻辑。如果你用某种方法把它全部隔离开来,反复调用它,它很可能每次都要拆掉并重建到邮件服务器的连接,而身份验证等所涉及的延迟仍然会不必要地降低整个过程的速度。尽可能通过一个打开的连接向邮件服务器发送多封电子邮件。

        6
  •  6
  •   Augusto Barreto    9 年前

    这是一个 使用.Net 4.5.2+:

    BackgroundTaskRunner.FireAndForgetTaskAsync(async () =>
    {
        SmtpClient smtpClient = new SmtpClient(); // using configuration file settings
        MailMessage message = new MailMessage(); // TODO: Initialize appropriately
        await smtpClient.SendMailAsync(message);
    });
    

    其中BackgroundTaskRunner是:

    public static class BackgroundTaskRunner
    {     
        public static void FireAndForgetTask(Action action)
        {
            HostingEnvironment.QueueBackgroundWorkItem(cancellationToken => // .Net 4.5.2+ required
            {
                try
                {
                    action();
                }
                catch (Exception e)
                {
                    // TODO: handle exception
                }
            });
        }
    
        /// <summary>
        /// Using async
        /// </summary>
        public static void FireAndForgetTaskAsync(Func<Task> action)
        {
            HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => // .Net 4.5.2+ required
            {
                try
                {
                    await action();
                }
                catch (Exception e)
                {
                    // TODO: handle exception
                }
            });
        }
    }
    

    在Azure应用程序服务上就像一个魔咒。

        7
  •  4
  •   kbrimington    14 年前

    试试这个:

    var client = new System.Net.Mail.SmtpClient("smtp.server");
    var message = new System.Net.Mail.MailMessage() { /* provide its properties */ };
    client.SendAsync(message, null);
    
        8
  •  2
  •   JohnFx    14 年前

    下面是一个关于如何做到这一点的教程: Threading Tutorial C#

        9
  •  2
  •   CubanX    14 年前

    使用 SmtpClient SendAsync 在System.Net.Mail命名空间中。

        10
  •  1
  •   JaredReisinger    14 年前

    使用 Task Parallel Library 在.NET 4.0中,您可以执行以下操作:

    Parllel.Invoke(() => { YourSendMailMethod(); });
    

    cristina manu's 关于Parallel.Invoke()与显式任务管理的博客文章。