如何在Task.Run中调用异步方法?

时间:2016-08-22 05:18:25

标签: c# asp.net-mvc asynchronous async-await sendmail

我需要以Async方式发送邮件。我已经想出使用Razor Generator从剃刀视图生成Html模板。现在我需要使用SmtpClient.SendMailAsync将html作为Mail发送。但我发现Razor生成器需要相当长的时间,我不想在我的发送邮件方法中包含模板生成部分,因为发送邮件方法不应该关注获取Html模板。

我有示例代码:

public static void SendEmailAsync<TModel>(TModel model, string templatePath, string subj, string toEmail, string cc = null, string bcc = null)
    {

        string templateFilePath = HostingEnvironment.MapPath(templatePath);
        // Generate the email body from the template file.
        // 'templateFilePath' should contain the absolute path of your template file.
        if (templateFilePath != null)
        {
            Task.Run(() =>
            {
                var emailHtmlBody = Engine.Razor.RunCompile(File.ReadAllText(templateFilePath),
                templateFilePath, model.GetType(), model);
                SendEmailAsync(subj, emailHtmlBody, toEmail, cc, bcc);
            });
        }
        else
        {
            throw new System.Exception("Could not find mail template.");
        }
    }

和SendMailAsync的签名是:

static async Task SendEmailAsync(string subj, string message, string toEmail, string cc = null, string bcc = null)
    {
        //Reading sender Email credential from web.config file  
        string fromEmail = ConfigurationManager.AppSettings["FromEmail"].ToString();
        string fromName = ConfigurationManager.AppSettings["FromName"].ToString();

        //creating the object of MailMessage  
        MailMessage mailMessage = new MailMessage();
        mailMessage.From = new MailAddress(fromEmail, fromName); //From Email Id  
        mailMessage.Subject = subj; //Subject of Email  
        mailMessage.Body = message; //body or message of Email  
        mailMessage.IsBodyHtml = true;

        string[] toMuliId = toEmail.Split(',');
        foreach (string toEMailId in toMuliId)
        {
            mailMessage.To.Add(new MailAddress(toEMailId)); //adding multiple TO Email Id  
        }


        if (cc != null)
        {
            string[] ccId = cc.Split(',');

            foreach (string ccEmail in ccId)
            {
                mailMessage.CC.Add(new MailAddress(ccEmail)); //Adding Multiple CC email Id  
            }
        }

        if (bcc != null)
        {
            string[] bccid = bcc.Split(',');

            foreach (string bccEmailId in bccid)
            {
                mailMessage.Bcc.Add(new MailAddress(bccEmailId)); //Adding Multiple BCC email Id  
            }
        }

        SmtpClient smtp = new SmtpClient
        {
            EnableSsl = true,
            Credentials = new NetworkCredential("", "")
        };

        //network and security related credentials  
        await smtp.SendMailAsync(mailMessage); //sending Email  
    }

没有抛出异常,但我收到错误:

  

System.InvalidOperationException:此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为&lt;%@ Page Async =“true”%&gt;。此异常还可能表示尝试调用“异步void”方法,该方法通常在ASP.NET请求处理中不受支持。相反,异步方法应该返回一个Task,调用者应该等待它。

2 个答案:

答案 0 :(得分:1)

使用此:

class Base:

    def method(self, arg):
        # ...
        result = self._method(arg)
        # ...
        return result

    def _method(self, arg):
        raise NotImplementedError

答案 1 :(得分:0)

这个问题是每次发送电子邮件时都会运行以下方法(这会生成需要时间的初始类)

Engine.Razor.RunCompile

理想情况下,您应该调用以下方法,然后才会抛出错误,然后调用RunCompile

Engine.Razor.Run

有关使用带缓存的模板管理器

,请参阅this article