Отправляя массовые электронные письма в фоновом режиме - создать поток или использовать Treadpool?

StackOverflow https://stackoverflow.com/questions/4138405

Вопрос

У меня есть заявление, в котором действие вызывает ряд электронных писем, которые будут отправлены. Количество электронных писем переменное и может быть от 10 до 1000 за действие.

Я не хочу, чтобы приложение вешать в то время как электронные письма отправляются (таким образом, раздражают пользователя) и хотели бы отправить их в фоновом режиме.

В прошлом я не использовал темы, поэтому мне нужна ваша помощь. Вы бы создали потоки вручную или это хороший случай для использования потока? Я хочу, чтобы эта задача была низкой приоритетом и использовал наименьшее количество ресурсов, потому что я не против, даже если электронное письмо опоздало на 1 час.

Ценю вашу помощь
Марко

Это было полезно?

Решение

Вот еще одно предложение ... если вы используете DB, создайте задачу (то есть создайте таблицу, которая представляет собой задачу), связанную с сообщениями, которые необходимо отправлять и использовать Quartz.net Или аналогично (вы также можете создать службу Windows), которая ищет неполные задачи и выполняет их (отмечает их, как это сделано, если они выполнены успешно).

Другие советы

По правде говоря, потоки в ASP.NET - не очень хорошая идея. ASP.NET делает много утилизации ресурсов, когда запрос заканчивается, и отправляется обратно пользователю. Поскольку вы не хотите, чтобы пользователь ждал, вы столкнетесь с этим сценарием, где объекты ASP.NET, которые, по вашему мнению, являются безопасными в использовании, действительно утилизируются.

Лучший вариант - создать внешнюю службу (либо служба WCF, работающую в IIS, или служба Windows, в которой открыт интерфейс WCF), который страница .NET может вызвать асинхронно, и выполнить этот запрос, пока он не завершится. Без беспокойства о потоке и т. Д. Он работает в собственном процессе, и когда он будет выполнен, он завершается. Поскольку вам не все равно сказать пользователю, что сделано, вам не придется беспокоиться об этом. Таким образом, если вам нужно иметь какую -то другую страницу, используйте тот же сервисный интерфейс, его следует вызвать.

Страницы на начале работы с WCF:

http://bloggingabout.net/blogs/dennis/archive/2007/04/20/wcf-simple-example.aspx

http://msdn.microsoft.com/en-us/library/bb332338.aspx

http://www.c-sharpcorner.com/articles/articlelisting.aspx?sectionId=1&subsectionId=192

Как начать использовать WCF/WPF?

Поэтому мое предложение состоит в том, чтобы использовать Threadpool. Это позволило бы вам стоять в очереди на все, чтобы запустить каждый из них отдельно, заставляя его использовать меньше ресурсов, но, конечно, потребуется больше времени для обработки всего, но, как вы сказали, время не является проблемой.

Вы можете просто использовать Фоновый работник учебный класс.

Связанная страница MSDN имеет хороший пример с отчетностью о прогрессе и возможности отменить операцию.

Редактировать:
Отчеты о прогрессе и отмене могут быть не подходящими в веб -приложении, но фоновый работник обрабатывает все грязные вещи с созданием потока для вас.

Edit2:
Если вы хотите отправить много писем параллельно, вы можете посмотреть Задача параллельная библиотека.

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

Если это слишком много, вы можете создать новый планировщик, который снижает параллелизм: http://msdn.microsoft.com/en-us/library/ee789351.aspx

static void StartMailTasks(string[] addresses)
{
    List<Task> tasks = new List<Task>();
    foreach (var address in addresses)
    {
        tasks.Add(Task.Factory.StartNew(Email, address));
    }

    Task.Factory.ContinueWhenAll(tasks.ToArray(), AllDone, TaskContinuationOptions.OnlyOnRanToCompletion);
    Task.Factory.ContinueWhenAny(tasks.ToArray(), ReportError, TaskContinuationOptions.OnlyOnFaulted);
}

static void AllDone(Task[] tasks)
{
    // All is well
}

static void ReportError(Task errorTask)
{
    // Log or report the error
}

static void Email(object state )
{
    // send the e-mail  
    // Can throw error, if needed
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top