#c# #email #asp.net-core #asynchronous
#c# #Адрес электронной почты #asp.net-core #асинхронный
Вопрос:
Я разрабатываю веб-приложение с ASP.NET Core MVC 3.1, с использованием Visual Studio 2019 Community Edition, версия 16.8.0 (обновлено 11.11.2020).
В этом приложении администратор может вводить пользователей в базу данных. Всякий раз, когда вводится пользователь, этому пользователю отправляется сообщение электронной почты в фоновом режиме. Чтобы предотвратить задержку отображения страницы подтверждения, сообщение электронной почты отправляется асинхронно. Это работает нормально, за исключением случаев, когда администратор вводит несколько пользователей в быстрой последовательности. Тогда отправляется только одно или два сообщения, поскольку почтовый сервер накладывает ограничение на количество потоков, которые могут использоваться одновременно.
Если кто-нибудь может сказать мне, как справиться с этой проблемой, я был бы признателен.
Вот некоторые сведения о моем текущем коде:
Прежде всего, есть функция для вставки пользователя в базу данных. Если вставка завершается успешно, эта функция вызывает другую функцию, которая отправляет новому пользователю сообщение электронной почты.
Функция вставки имеет следующий шаблон:
void InsertUser(...)
{
// Insertion code here
// If operation successful:
Task t = SendGreetingsAsync(...);
}
Как вы можете видеть, InsertUser(…) не «ожидает» отправки greetingsasync(…) . Если бы это произошло, преимущество асинхронности было бы потеряно. По крайней мере, так я понимаю.
SendGreetingsAsync(…) вызывает функцию SendGreetings(…) следующим образом:
async Task SendGreetingsAsync(...)
{
await Task.Delay(1);
SendGreetings(...);
}
SendGreetings(…) — это синхронная функция по следующему шаблону:
void SendGreetings(...)
{
// Send an e-mail to the user specified in the parameter list
}
Резюмируя, проблема заключается в том, как предотвратить задержки отображения из-за фоновых сообщений электронной почты, когда несколько пользователей вводятся в быстрой последовательности, не вызывая проблем на стороне электронной почты.
Любая помощь будет принята с благодарностью!
Комментарии:
1. Если вы отправляете электронные письма — вам нужно где-то их сохранить, чтобы иметь возможность повторить попытку. Существуют абсолютно веские причины, по которым SMTP-сервер временно отклоняет ваше электронное письмо, помимо той, с которой вы столкнулись, и в этом случае вам придется повторить попытку позже. Или вы можете использовать соответствующий SMTP-сервер, который сделает это за вас. Отправка электронных писем из веб-приложения способом «запустить и забыть» очень ненадежна.
2. Спасибо за этот совет и за столь быстрый ответ. Не могли бы вы объяснить, как «использовать правильный SMTP-сервер, который делает это за вас»?
Ответ №1:
Используйте SemaphoreSlim для ограничения параллелизма через путь кода.
async Task SendGreetingsAsync(...)
{
try
{
await semaphore.WaitAsync();
SendGreetings(...);
}
finally
{
semaphore.Release();
}
}
Или добавьте электронные письма в BlockingCollection и попросите один фоновый поток отправить все электронные письма.
Комментарии:
1. Большое тебе спасибо, Дэвид. Я прочитаю об этих инструментах, о которых я никогда раньше не слышал.