Мне нужно отправить почту по пути Async. Я решил использовать Razor Generator для генерации шаблона Html с точки зрения бритвы. теперь мне нужно использовать SmtpClient.SendMailAsync для отправки html как Mail. но я обнаружил, что генератор Razor занимает довольно много времени, и я не хочу включать часть генерации шаблона в свой метод отправки почты, поскольку метод отправки почты не должен беспокоиться о получении шаблона Html.Как вызвать метод Async в Task.Run?
У меня есть пример кода:
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: An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>. This exception may also indicate an attempt to call an "async void" method, which is generally unsupported within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller should await it.
Основная проблема заключается в том, что ваш 'static vo id SendEmailAsync (...) 'метод должен быть' static async Задача SendEmailAsync (...) 'вместо этого. При этом вы можете «подождать» 'Task.Run()'. Это точно такая же проблема, как обсуждалось в ряде предыдущих заданных вопросов, включая отмеченный дубликат. –
@PeterDuniho Я просто не хочу добавлять ключевое слово async ко всем моим методам вплоть до контроллера. –
@Aron Да, спасибо, я думаю, что это та же проблема. –