С# Таймер или Thread.Sleep

Я запускаю службу Windows и использую цикл и Thread.Sleep для повторения задачи, было бы лучше использовать метод таймера?

Если да, пример кода будет большим

В настоящее время я использую этот код для повторения

int curMinute;
int lastMinute = DateTime.Now.AddMinutes(-1).Minute;

while (condition)
{
   curMinute = DateTime.Now.Minute;

   if (lastMinute < curMinute) {
         // do your once-per-minute code here
         lastMinute = curMinute;
   }

   Thread.Sleep(50000);      // sleeps for 50 seconds

   if (error condition that would break you out of this) {
       break;      // leaves looping structure
   }
}

Ответ 1

class Program
{
    static void Main(string[] args)
    {
        Timer timer = new Timer(new TimerCallback(TimeCallBack),null,1000,50000);
        Console.Read();
        timer.Dispose();
    }

    public static void TimeCallBack(object o)
    {
      curMinute = DateTime.Now.Minute;
      if (lastMinute < curMinute) {
       // do your once-per-minute code here
       lastMinute = curMinute;
    }
}

Код может напоминать что-то вроде выше

Ответ 2

Таймер - лучшая идея, ИМО. Таким образом, если ваша служба попросит остановиться, она может отреагировать на это очень быстро и просто не вызовет обработчик таймера снова... если вы спите, менеджеру службы придется либо ждать 50 секунд, либо убить нить, ни одна из которых ужасно приятна.

Ответ 3

Важно понимать, что ваш код будет спать в течение 50 секунд между окончанием одного цикла и началом следующего...

Таймер будет вызывать ваш цикл каждые 50 секунд, что не совсем то же самое.

Они оба действительны, но таймер, вероятно, то, что вы ищете здесь.

Ответ 4

Остерегайтесь, чтобы вызов Sleep() заблокировал службу, поэтому, если служба запрошена для остановки, она не будет реагировать на длительность вызова Sleep().

Ответ 5

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

Ответ 6

Не совсем отвечая на вопрос, а не имея

   if (error condition that would break you out of this) {
       break;      // leaves looping structure
   }

Вероятно, вы должны иметь

while(!error condition)

Кроме того, я бы пошел с Timer.

Ответ 7

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

В ответах содержатся некоторые ссылки, которые могут оказаться полезными.

Ответ 8

Я использовал оба таймера и Thread.Sleep(x), либо либо, в зависимости от ситуации.

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

Если у меня есть часть кода, которая может занять больше времени, чем таймер задержки (например, получение файлов с удаленного сервера по FTP, где я не контролирую или не знаю, задержка сети или размер/количество файлов) Я буду ждать фиксированного периода времени между циклами.

Оба действительны, но, как указывалось ранее, они делают разные вещи. Таймер запускает ваш код каждые x миллисекунд, даже если предыдущий экземпляр не был завершен. Thread.Sleep(x) ждет определенного периода времени после завершения каждой итерации, поэтому полная задержка на цикл всегда будет длиннее (возможно, не намного), чем период ожидания.

Ответ 9

Вы можете использовать любой из них. Но я думаю, что Sleep() легко, понятно и короче реализовать.

Ответ 10

Я тоже согласен, использование таймера - лучший вариант. В прошлом я пробовал решение, подобное вашему, и у меня возникли проблемы с циклом пропусков, и мне пришлось бы ждать еще одного Thread.Sleep(), прежде чем он снова запустится. Кроме того, это вызвало всевозможные проблемы с остановкой службы, я получал бы постоянные ошибки о том, как он не реагировал и должен был быть закрыт.

Код @Prashanth должен быть именно тем, что вам нужно.

Ответ 11

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

Например..

<!-- language: c# -->
public enum State
{
    Idle = 0,
    Processing = 1,
    Stop = 100,
}
public void Run()
{
    State state = State.Idle;   // could be a member variable, so a service could stop this too

    double intervalInSeconds = 60;
    System.DateTime nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds);
    while (state != State.Stop)
    {
        switch (state)
        {
            case State.Idle:
                {
                    if (nextExecution > System.DateTime.Now)
                    {
                        state = State.Processing;
                    }
                }
                break;
            case State.Processing:
                {
                    // do your once-per-minute code here

                    // if you want it to stop, just set it state to stop.
                    // if this was a service, you could stop execution by setting state to stop, also
                    // only time it would not stop is if it was waiting for the process to finish, which you can handle in other ways

                    state = State.Idle;
                    nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds);
                }
                break;
            default:
                break;
        }

        System.Threading.Thread.Sleep(1);
    }
}