Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .SendMailAsync()在MVC中的使用_C#_Asp.net Mvc - Fatal编程技术网

C# .SendMailAsync()在MVC中的使用

C# .SendMailAsync()在MVC中的使用,c#,asp.net-mvc,C#,Asp.net Mvc,我正在尝试从我的MVC应用程序发送电子邮件,当我使用.send()方法时,它可以正常发送,但需要一段时间才能返回,因此我想使用.SendMailAsync()函数,但在执行过程中收到以下错误 此时无法启动异步操作。异步操作只能在异步处理程序或模块内启动,或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保已标记该页面 这是我的代码示例。如何使用.SendMailAsync()将其配置为发送 电子邮件包装类: using System.Net.Mail; namespace

我正在尝试从我的MVC应用程序发送电子邮件,当我使用.send()方法时,它可以正常发送,但需要一段时间才能返回,因此我想使用.SendMailAsync()函数,但在执行过程中收到以下错误

此时无法启动异步操作。异步操作只能在异步处理程序或模块内启动,或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保已标记该页面

这是我的代码示例。如何使用.SendMailAsync()将其配置为发送

电子邮件包装类:

using System.Net.Mail;

namespace Helpers
{
    public class Email
    {
        // constants
        private const string HtmlEmailHeader = "<html><head><title></title></head><body style='font-family:arial; font-size:14px;'>";
        private const string HtmlEmailFooter = "</body></html>";

        // properties
        public List<string> To { get; set; }
        public List<string> CC { get; set; }
        public List<string> BCC { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }  

        // constructor
        public Email()
        {
            To = new List<string>();
            CC = new List<string>();
            BCC = new List<string>();
        }

        // send
        public void Send()
        {
            MailMessage message = new MailMessage();

            foreach (var x in To)
            {
                message.To.Add(x);
            }
            foreach (var x in CC)
            {
                message.CC.Add(x);
            }
            foreach (var x in BCC)
            {
                message.Bcc.Add(x);
            }

            message.Subject = Subject;
            message.Body = string.Concat(HtmlEmailHeader, Body, HtmlEmailFooter);
            message.BodyEncoding = System.Text.Encoding.UTF8;
            message.From = new MailAddress(From);
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            message.IsBodyHtml = true;

            SmtpClient client = new SmtpClient("relay.mail.server");

            client.SendMailAsync(message);            
        }
    }
}
使用System.Net.Mail;
命名空间帮助程序
{
公共类电子邮件
{
//常数
私有常量字符串HtmlEmailHeader=“”;
私有常量字符串HtmlEmailFooter=“”;
//性质
要{get;set;}的公共列表
公共列表CC{get;set;}
公共列表BCC{get;set;}
来自{get;set;}的公共字符串
公共字符串主题{get;set;}
公共字符串体{get;set;}
//建造师
公共电子邮件()
{
To=新列表();
CC=新列表();
BCC=新列表();
}
//发送
公共无效发送()
{
MailMessage=新的MailMessage();
foreach(变量x到)
{
添加消息(x);
}
foreach(CC中的变量x)
{
message.CC.Add(x);
}
foreach(BCC中的变量x)
{
message.Bcc.Add(x);
}
message.Subject=Subject;
message.Body=string.Concat(HtmlEmailHeader、Body、HtmlEmailFooter);
message.BodyEncoding=System.Text.Encoding.UTF8;
message.From=新邮件地址(From);
message.SubjectEncoding=System.Text.Encoding.UTF8;
message.IsBodyHtml=true;
SmtpClient=newSMTPClient(“relay.mail.server”);
client.SendMailAsync(消息);
}
}
}
控制器:

public ActionResult Index()
    {

        Email email = new Email();
        email.To.Add("to@email.com");
        email.From = "from@email.com";
        email.Subject = "Subject";
        email.Body = "<p><strong>Hello</strong></p><p>This is my first Email Message</p>";
        email.Send();
    }
public ActionResult Index()
{
电子邮件=新电子邮件();
email.To.Add(“to@email.com");
email.From=”from@email.com";
email.Subject=“Subject”;
email.Body=“你好这是我的第一封电子邮件

”; email.Send(); }
编辑

除了实际提出的问题,根本问题是发送电子邮件时造成的延迟。在这篇文章的帮助下,我进一步研究了实际问题:

修改了我的电子邮件包装器类以生成新线程来执行电子邮件处理:

using System.Net.Mail;

namespace Helpers
{
    public class Email
    {
        // constants
        private const string HtmlEmailHeader = "<html><head><title></title></head><body style='font-family:arial; font-size:14px;'>";
        private const string HtmlEmailFooter = "</body></html>";

        // properties
        public List<string> To { get; set; }
        public List<string> CC { get; set; }
        public List<string> BCC { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }  

        // constructor
        public Email()
        {
            To = new List<string>();
            CC = new List<string>();
            BCC = new List<string>();
        }

        // send
        public void Send()
        {
            MailMessage message = new MailMessage();

            foreach (var x in To)
            {
                message.To.Add(x);
            }
            foreach (var x in CC)
            {
                message.CC.Add(x);
            }
            foreach (var x in BCC)
            {
                message.Bcc.Add(x);
            }

            message.Subject = Subject;
            message.Body = string.Concat(HtmlEmailHeader, Body, HtmlEmailFooter);
            message.BodyEncoding = System.Text.Encoding.UTF8;
            message.From = new MailAddress(From);
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            message.IsBodyHtml = true;

            SmtpClient client = new SmtpClient("relay.mail.server");

            new Thread(() => { client.Send(message); }).Start();        
        }
    }
}
使用System.Net.Mail;
命名空间帮助程序
{
公共类电子邮件
{
//常数
私有常量字符串HtmlEmailHeader=“”;
私有常量字符串HtmlEmailFooter=“”;
//性质
要{get;set;}的公共列表
公共列表CC{get;set;}
公共列表BCC{get;set;}
来自{get;set;}的公共字符串
公共字符串主题{get;set;}
公共字符串体{get;set;}
//建造师
公共电子邮件()
{
To=新列表();
CC=新列表();
BCC=新列表();
}
//发送
公共无效发送()
{
MailMessage=新的MailMessage();
foreach(变量x到)
{
添加消息(x);
}
foreach(CC中的变量x)
{
message.CC.Add(x);
}
foreach(BCC中的变量x)
{
message.Bcc.Add(x);
}
message.Subject=Subject;
message.Body=string.Concat(HtmlEmailHeader、Body、HtmlEmailFooter);
message.BodyEncoding=System.Text.Encoding.UTF8;
message.From=新邮件地址(From);
message.SubjectEncoding=System.Text.Encoding.UTF8;
message.IsBodyHtml=true;
SmtpClient=newSMTPClient(“relay.mail.server”);
新线程(()=>{client.Send(message);}).Start();
}
}
}

诚然,错误有点迟钝,但它真正告诉您的是,您正在从同步方法调用异步方法,这是不允许的。如果要使用异步,则必须在整个链上使用异步

因此,首先需要更改
Send
方法定义以返回
任务

public async Task Send()
并将异步方法调用设置为等待:

await client.SendMailAsync(message);
然后,对您的操作执行相同的操作:

public async Task<ActionResult> Index()
更新

Async并不像我认为的那样。当请求调用您的操作时,在操作中的所有代码完全执行之前,它不会返回响应。Async并不是让动作更快地返回响应的魔杖。您的任务(在本例中,发送电子邮件)所需时间与所需时间相同,并且无论是否异步,在任务完成之前,操作都不会返回响应

那么为什么要使用异步呢?因为async所做的是从服务器池中释放线程。假设IIS运行在一个相当标准的配置中,您可能有大约1000个可用线程。这通常称为“最大请求”,因为通常1个请求==1个线程。因此,如果您的服务器负载很重,并且部署的请求超过了“最大请求数”,那么每个后续请求都将排队,直到池中的线程再次可用。如果所有线程都在等待完成某项任务,那么服务器实际上会死锁。但是,当您使用async时,您本质上告诉IIS,“我在等待一些东西。这是我的线程返回,所以您可以使用它来处理另一个请求。当我需要返回它时,我会通知您。”
await email.Send();
    public void Send(MailAddress toAddress, string subject, string body, bool priority)
    {
        Task.Factory.StartNew(() => SendEmail(toAddress, subject, body, priority), TaskCreationOptions.LongRunning);
    }

    private void SendEmail(MailAddress toAddress, string subject, string body, bool priority)
    {
        MailAddress fromAddress = new MailAddress(WebConfigurationManager.AppSettings["SmtpFromAddress"]);
        string serverName = WebConfigurationManager.AppSettings["SmtpServerName"];
        int port = Convert.ToInt32(WebConfigurationManager.AppSettings["SmtpPort"]);
        string userName = WebConfigurationManager.AppSettings["SmtpUserName"];
        string password = WebConfigurationManager.AppSettings["SmtpPassword"];

        var message = new MailMessage(fromAddress, toAddress);

        message.Subject = subject;
        message.Body = body;
        message.IsBodyHtml = true;
        message.HeadersEncoding = Encoding.UTF8;
        message.SubjectEncoding = Encoding.UTF8;
        message.BodyEncoding = Encoding.UTF8;
        if (priority) message.Priority = MailPriority.High;

        Thread.Sleep(1000);

        SmtpClient client = new SmtpClient(serverName, port);
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.EnableSsl = Convert.ToBoolean(WebConfigurationManager.AppSettings["SmtpSsl"]);
            client.UseDefaultCredentials = false;

            NetworkCredential smtpUserInfo = new NetworkCredential(userName, password);
            client.Credentials = smtpUserInfo;

            client.Send(message);

            client.Dispose();
            message.Dispose();
    }
public async Task<ActionResult> Index()
{
    Email email = new Email();
    email.SendAsync();
}
public async Task SendAsync()
{
    await Task.Run(() => this.send());
}
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
    LongRunningTaskAsync();
    return View();
}

public static async Task LongRunningTaskAsync()
{
    await Task.Run(() => LongRunningTask());
}

public static void LongRunningTask()
{
    Debug.WriteLine("LongRunningTask started");
    Thread.Sleep(10000);
    Debug.WriteLine("LongRunningTask completed");
}