使用smtp SendAsync发送邮件

时间:2017-01-23 09:46:50

标签: c# asp.net email asynchronous

这是我需要发送电子邮件时的错误。但是从那以后的错误是:

  

此时无法启动异步操作。异步   操作只能在异步处理程序中启动或   模块或在页面生命周期中的某些事件期间。如果这   执行页面时发生异常,确保页面为   标记为<%@ Page Async =" true" %取代。此例外也可能表示   试图调用" async void"方法,通常是不受支持的   在ASP.NET请求处理中。相反,异步方法   应该返回一个Task,调用者应该等待它。

我从MVC开始积累并使用类来跟踪页面的区域。我使用SendAsync的原因恰恰是发送电子邮件等更快。

只有在我尝试向用户发送电子邮件时才会出现此错误。

public static void NewPassword(string mail, string name, string password)
    {
        MailDefinition oMailDefinition = new MailDefinition();
        oMailDefinition.BodyFileName = "~/MailList/emailskabelon/NewPassword.html";
        oMailDefinition.From = FromMail;

        Dictionary<string, string> oReplacements = new Dictionary<string, string>();
        oReplacements.Add("<<navn>>", name);
        oReplacements.Add("<<password>>", password);

        System.Net.Mail.MailMessage oMailMessage = oMailDefinition.CreateMailMessage(mail, oReplacements, new LiteralControl());
        oMailMessage.Subject = NewpasswordTitle + WebsiteName;
        oMailMessage.IsBodyHtml = true;

        SmtpClient smtp = new SmtpClient(AzureApi);
        System.Net.NetworkCredential netcred = new System.Net.NetworkCredential(AzureName, AzurePassword);
        smtp.UseDefaultCredentials = false;
        smtp.EnableSsl = true;

        smtp.Credentials = netcred;
        smtp.Port = Convert.ToInt32("25");
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;

        using (var smtpClient = new SmtpClient())
        {
            smtp.SendAsync(oMailMessage, null);
        }
    }

我试图这样做:

public static async NewPassword(string mail, string name, string password)
        {
            ....
            using (var smtpClient = new SmtpClient())
            {
                await smtp.SendAsync(oMailMessage, null);
            }

我在这里看到:https://stackoverflow.com/a/35212320/7391454

3 个答案:

答案 0 :(得分:1)

将您的方法更改为:

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

并称之为:

var task = SendEmail(toEmailAddress, emailSubject, emailMessage);
var result = task.WaitAndUnwrapException();

在这里查看Asynchronously sending Emails in C#? 在这里How to call asynchronous method from synchronous method in C#?

答案 1 :(得分:0)

您还可以尝试在单独的线程中定义异步选项。 我相信您已经在页面中插入了异步标记。 如果一切正常,那么请尝试将代码放在下面。

 this.Page.RegisterAsyncTask(new PageAsyncTask(async ctoken => {
      var result = await SomeOperationAsync(ctoken);
      // result operations.
}));

答案 2 :(得分:0)

并没有真正回复您的原始问题,但只是想强调您最好不要在不保持调用线程等待的情况下调用发送代码的电子邮件。虽然您正在使用async / await,但在用户的角度来看,当服务器完成发送电子邮件时,您仍在浏览器中等待。它可能只有几毫秒,但让后台工作人员处理它仍然会更好。

所以IMO,使用HostingEnvironment.QueueBackgroundWorkItem(x=> SendEmail());将是一种更好的方法。

话虽如此,如果应用程序域在中间回收,您仍然存在异步任务被终止的轻微风险。但在我看来,这种情况极不可能。即使发生这种情况,您也可以使用取消令牌并绕过它。