问题描述: 我想创建一个新线程来发送一些电子邮件。实现:
Thread _thread = new Thread(new ThreadStart(StartSendingEmails));
该函数名为:
public void StartSendingEmails()
{
var engine = new SendGridEmailEngine(From, FromName)
{
TemplateUrl = _templateUrl,
QueryValues = _queryValues,
MailHeaders = _mailHeaders
};
engine.SendEmail(EmailContent, Subject);
}
发件人功能:
public void SendEmail(string emailContent, string subject)
{
int counter = 0;
LastResponseReceived = DateTime.Now;
foreach (var listItem in QueryValues)
{
//other operations....
// 50 emails stack => wait...
while (counter - ReceivedResponses > 50)
Thread.Sleep(100);
//increase number of sent emails
counter++;
SendEmail(_from, _fromName);
}
//wait for all responses to be received
while (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes <= 2)
Thread.Sleep(1000);
//force exit if more than 2 min left and not all the responses received
if (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes >= 2)
WriteLog(string.Format("Forced exit!);
}
致电:
public void SendEmail(string from, string fromName)
{
//other operations
client.SendCompleted += new SendCompletedEventHandler(client_SendCompleted);
}
void client_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
ReceivedResponses++;
LastResponseReceived = DateTime.Now;
if (e.Error != null)
{
}
else
{
SentEmailsSuccessfully++;
}
}
这就是问题所在。发送所有电子邮件但线程不等待所有响应。有没有办法比我用过的东西保持活力?
//wait for all responses to be received
while (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes <= 2)
Thread.Sleep(1000);
答案 0 :(得分:2)
您应该将每个完整的发送操作封装到Task
对象中。您可以await
Task.WhenAll
的结果等待所有任务完成。
List<Task> sendTasks = new List<Task>();
foreach (var listItem in QueryValues)
{
sendTasks.Add(SendEmailAsync(_from, _fromName);
}
// wait for all responses to be received
await Task.WhenAll(sendTasks);
要提供一种取消操作的方法,如果花费的时间太长,只需使用超时的CancellationTokenSource
。
using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2)))
{
List<Task> sendTasks = new List<Task>();
foreach (var listItem in QueryValues)
{
sendTasks.Add(SendEmailAsync(_from, _fromName, cts.Token);
}
// wait for all responses to be received
await Task.WhenAll(sendTasks.ToArray()).ConfigureAwait(false);
}