Многопоточный таймер службы Windows - PullRequest
1 голос
/ 13 июня 2011

Я создаю службу Windows, которая будет проверять пользователей по расписанию в базе данных.Служба проверяет базу данных на плановые проверки каждые десять минут.После запуска аудита он отмечает время начала в таблице базы данных, поэтому он не запустится снова, если это займет более десяти минут.

Мой вопрос: приемлем ли следующий код для того, что я делаю, ия должен использовать многопоточность каждый раз по истечении 10 минут, и если да, то как мне это сделать?

Мой пример кода:

protected override void OnStart(string[] args)
{
    var aTimer = new Timer(600000);
    aTimer.Elapsed += ATimerElapsed;
    aTimer.Interval = 600000;
    aTimer.Enabled = true;
    GC.KeepAlive(aTimer);
}

private static void ATimerElapsed(object sender, ElapsedEventArgs e)
{
    try
    {
         Worker.ProcessScheduledAudits();
    }
    catch (Exception ex)
    {
         EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error);
    }                
}

Ответы [ 2 ]

2 голосов
/ 13 июня 2011

System.Threading.Timer будет использовать поток из пула потоков для запуска обработчика Elapsed. Итак, вы уже используете многопоточность, просто используя таймер. На самом деле, все таймеры используют какой-то фоновый поток; они просто различаются по тому, как они многопоточны, чтобы делать то, что наиболее целесообразно для предполагаемого использования.

Если вам нужно что-то запускать раз в десять минут, но также убедитесь, что два обработчика никогда не запускаются одновременно, попробуйте установить флаг «В настоящее время» в методе Elapsed и проверить его перед выполнением любых тяжелых работ.

    protected override void OnStart(string[] args)
    {
        var aTimer = new Timer(600000);
        aTimer.Elapsed += ATimerElapsed;
        aTimer.Interval = 600000;
        aTimer.Enabled = true;
        GC.KeepAlive(aTimer);
    }

    private static currentlyRunning;

    private static void ATimerElapsed(object sender, ElapsedEventArgs e)
    {
        if(currentlyRunning) return;
        currentlyRunning = true;
        try
        {
            Worker.ProcessScheduledAudits();
        }
        catch (Exception ex)
        {
            EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error);
        }
        currentlyRunning = false;
    }

Теоретически, это может привести к гонке, но так как вы только начинаете с этого события каждые 10 минут, шансы ЧРЕЗВЫЧАЙНО маловероятны.

1 голос
/ 13 июня 2011

Этот код уже равен"использование многопоточности". Предполагая, что ваш экземпляр Timer равен System.Timers.Timer, ваш обработчик Elapsed будет работать в потоке пула потоков.

Если это не то, что вы хотите, вы можете использовать свойство SynchronizingObject для изменения поведения отправки. Для получения дополнительной информации прочитайте документацию MSDN .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...