Отправка электронной почты SMTP, принудительно закрываемой в консольном приложении, прежде чем она сможет отправлять электронную почту в .NET - PullRequest
0 голосов
/ 17 октября 2018

У меня есть приложение для уведомлений по электронной почте, которое отправляет электронные письма, и мы делаем это в консольном приложении, которое запускается каждые 5 минут.Мы запускаем часть электронной почты в задаче, чтобы она могла перейти к другой группе уведомлений.

Однако мы запускаем одно уведомление, консоль закрывается и электронное письмо не отправляется.На стороне SMTP говорится, что хост был принудительно закрыт.Как сохранить консольное приложение активным, пока все задачи не будут завершены, но при этом иметь возможность многопоточности.

Операция чтения не удалась.Передано байтов: 0 Удаленный IP: 44.444.444.44, Сессия: 124992, Код: 10054, Сообщение: Существующее соединение было принудительно закрыто удаленным хостом

private Task SendFromServer(MailMessage mailMessage, bool reuse, bool useServerSmtp)
{
    return Task.Factory.StartNew(() =>
                {
                    var smtp = new SmtpClient();
                    smtp.Send(mailMessage);
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.InnerException ?? ex);
                }
                finally
                {
                    if(!reuse)
                        mailMessage.Dispose();
                }
            });
        }
}

1 Ответ

0 голосов
/ 17 октября 2018

Используйте SmtpClient.SendMailAsync, который можно ожидать.

private async Task SendFromServer(MailMessage mailMessage) {
    using (var smtp = new SmtpClient()) {
        try {
            await smtp.SendMailAsync(mailMessage);
        } catch (Exception ex) {
            Logger.Error(ex.InnerException ?? ex);
        }
    }
}

, и поскольку он вызывается в консольном приложении, вам нужно будет вызывать его как

//get all notification tasks. Assuming notifications => List<MailMessage>
var tasks = notifications.Select(message => SendFromServer(message));
//execute all asynchronously
Task.WhenAll(tasks).GetAwaiter().GetResult();

, поэтомуконсольное приложение ждет, пока все они выполнят свои задачи

...