![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Отдельный поток
Если мы рассылаем электронную почту большому количеству людей, то обработка может занять много времени. Для этого я пользуюсь следующим принципом: · Создаем отдельный поток, который проверяет, если ли исходящие письма готовые к отправке · При создании рассылки создаются письма и записываются в БД · Поток проверяет состояние БД на наличие писем · Письма извлекаются из БД последовательно (письмо может удалиться, может только обнулить содержимое письма (чтоб сэкономить размер БД). · Письмо отправляется. · Возвращается к проверке. Отдельный поток запускается в Application_Start. Таймер устанавливается на повторение через 1 минуту: public class MvcApplication: System.Web.HttpApplication { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private Thread mailThread { get; set; }
protected void Application_Start() { var adminArea = new AdminAreaRegistration(); var adminAreaContext = new AreaRegistrationContext(adminArea.AreaName, RouteTable.Routes); adminArea.RegisterArea(adminAreaContext);
var defaultArea = new DefaultAreaRegistration(); var defaultAreaContext = new AreaRegistrationContext(defaultArea.AreaName, RouteTable.Routes); defaultArea.RegisterArea(defaultAreaContext);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles);
mailThread = new Thread(new ThreadStart(ThreadFunc)); mailThread.Start(); }
private static void ThreadFunc() { while (true) { Try { var mailThread = new Thread(new ThreadStart(MailThread)); mailThread.Start(); logger.Info(" Wait for end mail thread"); mailThread.Join(); logger.Info(" Sleep 60 seconds"); } catch (Exception ex) { logger.ErrorException(" Thread period error", ex); } Thread.Sleep(60000); } } private static void MailThread() { var repository = DependencyResolver.Current.GetService< IRepository> (); while (MailProcessor.SendNextMail(repository)) { } } }
Рассмотрим класс MailProcessor (но не будем его создавать): public class MailProcessor { public static bool SendNextMail(IRepository repository) { var mail = repository.PopMailQueue(); if (mail! = null) { MailSender.SendMail(mail.Email, mail.Subject, mail.Body); return true; } return false; } } MailProcessor.SendNextMail(repository) – посылает следующее письмо, если писем нет – возвращает false Поток MainThread дожидается выполнение MailThread и делает перекур на одну минуту. И далее. Если в БД новых писем нет – дальше курим одну минуту.
|