我开发了一个主要使用SMTP发送电子邮件的应用程序。
MailMessage mail = new MailMessage();
mail.From = new MailAddress("from", "to");
mail.Subject = "subject";
mail.Body = "body";
SmtpClient client = new SmtpClient("my domain");
client.Credentials = new NetworkCredential(from, "MyPass");
client.Send(mail);
这很好但现在我想在同一时间发送几条消息而不必等待,所以我将所有消息放在一个列表中:
List<MailMessage> emails = new List<MailMessage>();
emails.Add(new MailMessage (...));
emails.Add(new MailMessage (...));
emails.Add(new MailMessage (...));
...
我想打开每封电子邮件的新Thread
:
// Generate and execute all mails concurrently
var emailTasks = emails.Select(msg =>
{
client = new SmtpClient();
return client.SendAsync(msg);
});
// Asynchronously wait for all of them to complete.
await Task.WhenAll(emailTasks);
得到了这个错误:
没有SendMailAsync,最后一行代码也有错误: 等待&#39;等待&#39;运算符只能在异步方法中使用。考虑 使用&#39; async&#39;标记此方法修饰符并改变其回报 输入&#39;任务&#39;
答案 0 :(得分:0)
发生此错误是因为您在所有线程捕获的同一SmtpClient
实例上进行了多次SMTP调用。
您可以在SmtpClient.Send
的源代码中看到它(为简洁而缩短):
try
{
// If there is already an ongoing SMTP request
if (InCall)
{
throw new InvalidOperationException(SR.GetString(SR.net_inasync));
}
}
通常,您不需要使用任何线程来执行I / O绑定操作,因为它们本质上是异步的。
相反,您可以使用async-await
来利用异步API:
// Generate and execute all mails concurrently
var emailTasks = emails.Select(msg =>
{
var client = new SmtpClient();
return client.SendMailAsync(msg));
});
// Asynchronously wait for all of them to complete.
await Task.WhenAll(emailTasks);