I am trying to send multiple messages using SendMailAsync and I am trying to pass a cancellation token to interrupt the sending process when the cancellation has been requested.
static void Send(SmtpClientFactory factory, IEnumerable<MailMessage> messages)
{
Task.WaitAll(SendAsync(factory, messages, CancellationToken.None));
}
static async Task SendAsync(SmtpClientFactory factory, IEnumerable<MailMessage> messages, CancellationToken token)
{
await Task.Run(async () =>
{
using (SmtpClient smtpClient = factory())
{
foreach (MailMessage message in messages)
{
await smtpClient.SendMailAsync(message).ConfigureAwait(false);
}
}
}, token);
}
When I use the non-async Send, it gets into a deadlock. How can I send my message synchrnously and use a cancellation token to cancel when the time is up?
You can combine CancellationToken.Register
and SmtpClient.SendAsyncCancel
to do what you need:
static async Task SendAsync(SmtpClientFactory factory, IEnumerable<MailMessage> messages, CancellationToken token)
{
await Task.Run(async () =>
{
using (SmtpClient smtpClient = factory())
{
foreach (MailMessage message in messages)
{
token.ThrowIfCancellationRequested();
using (token.Register(() => smtpClient.SendAsyncCancel()))
{
await smtpClient.SendMailAsync(message).ConfigureAwait(false);
}
}
}
}, token);
}
Keep in mind that SmtpClient
is officially deprecated :
SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead
Not only is MailKit threadsafe, but it's far more flexible in terms of message construction, and it supports CancellationToken
to boot!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.