Выполнение действий по таймеру

  • Михаил
  • 12 мин. на прочтение
  • 94
  • 12 Dec 2012
  • 12 Dec 2012

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

Например, определим модуль, который будет отправлять письмо на почту в определенное время:

public class TimerModule : IHttpModule
{
    static Timer timer;
    long interval = 30000; //30 секунд
    static object synclock = new object();
    static bool sent=false;
 
    public void Init(HttpApplication app)
    {
        timer = new Timer(new TimerCallback(SendEmail), null, 0, interval);
    }
 
    private void SendEmail(object obj)
    {
        lock (synclock)
        {
            DateTime dd = DateTime.Now;
            if (dd.Hour == 1 && dd.Minute == 30 && sent == false)
            {
                // настройки smtp-сервера, с которого мы и будем отправлять письмо
                SmtpClient smtp = new System.Net.Mail.SmtpClient("smtp.gmail.com", 587);
                smtp.EnableSsl = true;
                smtp.Credentials = new System.Net.NetworkCredential("somemail@gmail.com", "password");
                 
                // наш email с заголовком письма
                MailAddress from = new MailAddress("somemail@gmail.com", "Test");
                // кому отправляем
                MailAddress to = new MailAddress("othermail@yandex.ru");
                // создаем объект сообщения
                MailMessage m = new MailMessage(from, to);
                // тема письма
                m.Subject = "Test mail";
                // текст письма
                m.Body = "Рассылка сайта";
                smtp.Send(m);
                sent = true;
            }
            else if (dd.Hour != 1 && dd.Minute !=30)
            {
                sent = false;
            }
        }
    }
    public void Dispose()
    { }
}

 

Данный модуль настроен на отправку письма в 1:30. В методе Init() запускается таймер, который каждые 30000 миллисекунд (30 секунд) вызывает метод SendEmail()

Метод SendEmail() с помощью оператора lock определяет критическую секцию, доступ к которой одновременно возможен только для одного потока.

Для управления отправкой мы проверяем текущее время и значение переменной sent и в зависимости от результатов проверки отправляем письмо.

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

И после определения модуля зарегистрируем его в web.config:

<system.webServer>
  <modules>
    <add name="Timer" type="MvcTimerApp.Modules.TimerModule"/>
  </modules>
</system.webServer>