0

我有我写的这个方法,当用户按下按钮时会发送一封电子邮件。现在我面临的问题是,每当用户按下按钮时,表单都会冻结几秒钟,然后发送电子邮件。所以该方法有效,但我不明白为什么表格会冻结。

string emailAddress = tbEmailAddress.Text + cbEmailAddress.Text;
string emailPassword = tbEmailPassword.Text;
string emailRecipient = tbEmailRecipient.Text;
string emailSubject = tbEmailSubject.Text;
string emailBody = rtbEmailBody.Text;
string smtpHost;
string smtpPort;

MailMessage email = new MailMessage(emailAddress, emailRecipient);

email.Subject = emailSubject;
email.Body = emailBody;

SmtpClient smtp = new SmtpClient("smtp.live.com", 587);
smtp.EnableSsl = true;
smtp.Credentials = new System.Net.NetworkCredential(emailAddress, emailPassword);

smtp.Send(email);
smtp.Dispose();

有没有办法解决我面临的这个问题?

先感谢您。

4

5 回答 5

4

表单冻结是因为该方法需要在返回控制之前完成,并且发送邮件需要一些时间。您可以异步运行该方法。

如果您使用的是 .NET framework 4.5 和 C# 5,则可以使用async-await来实现您想要的。否则,您可以使用异步运行邮件发送Parallel.Invoke(() => { SendMail()}),或启动另一个线程来执行相同操作。

您可能还想看看:在 C# 中异步发送 System.Net.Mail.MailMessage和相关帖子:在 C# 中异步发送电子邮件?

于 2013-10-02T10:21:08.443 回答
1

只是另一种解决方案..我发现更好。任务是专门为帮助您管理这类事情而设计的。无需担心线程管理。它还允许您监视线程何时完成执行。

如果您将代码包装到它自己的方法中,您将能够执行以下操作:

var sendEmailTask = Task.Run(() => yourSendEmailMethod())
                            .ContinueWith(t => MessageBox.Show("Email sent"));

如前所述,问题是因为您的应用程序在单个线程上运行。在发送电子邮件期间,该线程将被阻止。如果您创建一个新线程(我的示例使用一个任务来执行此操作),电子邮件将使用该线程发送......并且您的应用程序 UI 将继续在其自己的线程上运行。

于 2013-10-02T10:26:58.220 回答
1

You can invoke the method on another Thread, try using Thread or Task. It's freezing because the UI thread is being blocked by your task thread, so you can seperate the thread to let the UI continue responding.

System.Threading.Thread execute = new System.Threading.Thread(delegate() 
{ /* execute method here here */ });
于 2013-10-02T10:25:39.713 回答
1

您应该使用SmtpClient.SendMailAsync(.NET 4.5) 或SendAsync

async Task SendMail()
{
    var email = CreateMailMessage();

    using (var smtp = new SmtpClient("smtp.live.com", 587) { 
          EnableSsl = true,
          Credentials = new NetworkCredential(emailAddress, emailPassword)
        })
    {
        await smtp.SendMailAsync(email);
    }
}
于 2013-10-02T10:32:48.780 回答
0

表单冻结是因为您使用程序的默认线程发送电子邮件。应用程序中的所有窗口都使用相同的线程来处理窗口事件。在您发送电子邮件时,Windows 无法处理任何 Windows 消息。将电子邮件发送到后台线程,然后您的应用程序将不会被阻止。

于 2013-10-02T10:21:31.220 回答