C#使用取消令牌异步发送多封电子邮件

时间:2018-06-12 03:20:34

标签: c# async-await smtpclient

我正在尝试使用SendMailAsync发送多条消息,我正在尝试传递取消令牌,以便在请求取消时中断发送过程。

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);
}

当我使用非异步发送时,它会陷入死锁。如何同步发送消息并在时间到期时使用取消令牌取消?

1 个答案:

答案 0 :(得分:2)

您可以合并CancellationToken.RegisterSmtpClient.SendAsyncCancel来完成您的需要:

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);
}

请注意,SmtpClientofficially deprecated

  

SmtpClient及其类型网络设计不佳,我们强烈建议您使用https://github.com/jstedfast/MailKithttps://github.com/jstedfast/MimeKit代替

MailKit线程不仅安全,而且在消息构建方面更加灵活,它支持CancellationToken启动!