Поскольку отправка электронной почты является процессом, связанным с вводом / выводом, поэтому создание потоков для отправки электронной почты не приведет к значительному (если вообще потребуется) ускорению.
Если вы используете SMTP-сервер, который является частью Windows, токогда вы «отправляете» электронное письмо, оно фактически не отправляется в этот момент.Он находится в очереди на сервере, и сервер отправляет их так быстро, как может.Отправка электронных писем на самом деле является медленным процессом.
Я предполагаю, что я имею в виду два варианта:
- Просто отправляйте их последовательно и посмотрите, соответствует ли это вашим требованиям к производительности.
- Вы могли бы использовать концепцию параллельного программирования под названием «Параллельная передача данных». Я продемонстрировал ее на примерах в блоге Параллельная передача данных - параллельное программирование на C # /. NET
По сути, вы получаете все свои данные (за один раз).Причина в том, что получение данных в пакетах также замедляет ваш процесс, поэтому, если вы заинтересованы в производительности (именно поэтому я предполагаю, что вы пытаетесь использовать потоки), то не выполняйте многократные обходы на сервер базы данных.(который также связан с вводом / выводом на двух уровнях: сетевой ввод / вывод и дисковый ввод / вывод).
Получите ваши данные и разбейте их на куски или разделы.Это все объясняется в статье, на которую я указал.Наивной реализацией будет количество чанков, равное количеству ядер на машине.
Каждый чанк обрабатывается одним потоком.Когда все темы сделаны, все готово.С новыми функциями ThreadPool в .NET 4.0 (если вы используете Parallel.For или PLINQ или Tasks) вы получите некоторые другие преимущества, такие как «похищение работы» для дальнейшего ускорения работы.
Parallel.Я думаю, что / Parallel.ForEach будет хорошо работать для вас.
EDIT
Только что заметил требование .NET 3.5.Ну, концепции все еще применяются, но у вас нет Parallel.For / ForEach.Итак, вот реализация (измененная из моего сообщения в блоге), которая использует ThreadPool и использует метод параллельной передачи данных.
private static void SendEmailsUsingThreadPool(List<Recipient> recipients)
{
var coreCount = Environment.ProcessorCount;
var itemCount = recipients.Count;
var batchSize = itemCount / coreCount;
var pending = coreCount;
using (var mre = new ManualResetEvent(false))
{
for (int batchCount = 0; batchCount < coreCount; batchCount++)
{
var lower = batchCount * batchSize;
var upper = (batchCount == coreCount - 1) ? itemCount : lower + batchSize;
ThreadPool.QueueUserWorkItem(st =>
{
for (int i = lower; i < upper; i++)
SendEmail(recipients[i]);
if (Interlocked.Decrement(ref pending) == 0)
mre.Set();
});
}
mre.WaitOne();
}
}
private static void SendEmail(Recipient recipient)
{
//Send your Emails here
}
}
class Recipient
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
}
Итак, получите ваши данные и вызовите SendEmailUsingThreadPool (), передав их вашим данным.Конечно, не называйте свой метод так :).Если у вас есть DataSet / DataTable, просто измените реализацию, чтобы принять DataSet / DataTable.Этот метод позволяет разделить ваши данные на куски, чтобы вам не приходилось беспокоиться об этом.Просто позвоните.