当异步操作仍在等待时,异步模块或处理程序已经完成。

8

我有以下用于发送电子邮件的代码,它是可行的:

    private SmtpClient _client = new SmtpClient("smtp.gmail.com", 587)
    {
        Credentials = new NetworkCredential("address@gmail.com", "password"),
        EnableSsl = true
    };
    public void DoThis(){
    _client.Send("from@gmail.com", to.Email, "Subject", "Body");}
    public void DoThat(){
    _client.Send("from@gmail.com", to.Email, "Subject", "Body");}

但是当邮件发送时,它会阻塞Web应用程序,因此我决定尝试异步发送:

   public void DoThis(){
    var message = new MailMessage("from@gmail.com", to.Email, "Subject", "Body");
   _client.SendAsync(message, null);
   }

我可以看到该操作在调试时异步处理,但我总是得到以下消息:

当仍有异步操作挂起时,异步模块或处理程序已完成。

我做错了什么?


异步操作对长时间运行的进程不应在IIS内部处理这一事实没有任何改变。您应该将其放入任务表中,让定期执行的计划任务或Windows服务进行处理。 - Spencer Ruport
@RobVious 我遇到了同样的问题。你解决了吗? - Bitsian
@Bitsian,是的,请看下面我的回答。 - RobVious
1个回答

5
我最终通过以下方式重新制作了异步电子邮件发送方式:
public void SendAsyncEmail(MailMessage message)
        {

            var client = new SmtpClient("mail.hover.com", 587)
            {
                Credentials = new NetworkCredential("admin@site.com", "Covert00!"),
                EnableSsl = false
            };
            client.SendCompleted += (sender, error) =>
            {
                if (error.Error != null)
                {
                    // TODO: get this working
                    throw new WarningException("Email Failed to send.");
                }
                client.Dispose();
                message.Dispose();
            };
            ThreadPool.QueueUserWorkItem(o => client.SendAsync(message, Tuple.Create(client, message)));
        }

注意,这只是一个临时解决方案,正确的处理电子邮件的方式(似乎)是使用某种队列服务与工作角色或其他Windows服务配对以弹出消息。

请查看正确的做法:http://www.aspsnippets.com/Articles/How-to-send-email-Asynchronously-in-ASPNet-using-Background-Thread.aspx - niico
当我尝试这种方法时,我得到了这个错误:无法访问已释放的对象。对象名称:“System.Net.Mail.SmtpClient”。 - thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接