【发布时间】:2019-07-22 22:21:36
【问题描述】:
我有一个控制台应用程序,它所做的只是遍历所有客户并向特定客户发送电子邮件,然后关闭。我注意到 MailKit 中的一些功能提供异步,所以我尝试使用它们而不是非 aysnc,当我这样做时,它执行了第一条语句 (emailClient.ConnectAsync),然后我注意到我的控制台应用程序正在关闭。它没有崩溃。在我调用我的 SendReports() 函数后,执行返回到 Main() 并继续执行。
private static void Main(string[] args)
{
...
var reportServices = new ReportsServices();
reportServices.SendReportsToCustomers();
Log.CloseAndFlush(); // It executes the first await call then returns here.
}
internal class ReportsServices
{
public async void SendReportsToCustomers()
{
try
{
foreach (var customer in _dbContext.Customer)
{
...
await SendReport(customer.Id, repTypeId, freqName);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private async Task SendReport(int customerId, int repTypeId, string freqName)
{
try
{
...
var es = new EmailSender();
await es.SendAsync();
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
public class EmailSender
{
public async Task SendAsync()
{
try
{
var message = new MimeMessage();
...
using (var emailClient = new SmtpClient())
{
await emailClient.ConnectAsync("smtp.gmail.net", 587);
await emailClient.AuthenticateAsync("username", "password"); // If I put a debug break here, it doesn't hit.
await emailClient.SendAsync(message);
await emailClient.DisconnectAsync(true);
// If I use the following calls instead, my console app will not shutdown until all the customers are sent emails.
await emailClient.Connect("smtp.gmail.net", 587);
await emailClient.Authenticate("username", "password"); // If I put a debug break here, it doesn't hit.
await emailClient.Send(message);
await emailClient.Disconnect(true);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
我不明白为什么我的循环不能继续遍历所有客户? - 还有更多工作要做。不知道为什么它会跳回 Main 函数。
我所希望的是循环将继续通过所有客户并发送电子邮件;无需等待电子邮件发送完毕即可继续下一封邮件。
感谢您的帮助!
【问题讨论】:
-
await是非阻塞的。调用线程继续并行运行,而不是方法的其余部分。无论调用SendReportsToCustomers都不能在其上使用await,因为它不会返回Task。如果您想要阻止使用Task.Result。 -
I am still trying to get my head around this我建议从我的asyncintro 开始,然后是我的asyncbest practices。
标签: c# multithreading mailkit