P
P
PickGG2019-11-16 16:44:53
C++ / C#
PickGG, 2019-11-16 16:44:53

How to make a timer to do a long job?

There is a code.

// Создаем таймер из System.Threading
Timer timer = new Timer(OnTimer, state: null, dueTime: 0, period: 1000);

static void OnTimer(object state)
{
        Thread.Sleep(5000); // Симуляция работы
}

The problem is this.
Work goes 5 seconds. The timer interval is 1 second. As a result, in 1 second, 5 jobs will be launched simultaneously, which will be performed simultaneously. I would like the timer not to start a new one until the old one is completed.
I came up with this solution using System.Timers.Timer.
// Создаем таймер
timer = new System.Timers.Timer(1000);
timer.Elapsed += Timer_Elapsed;
timer.Start();

private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
            timer.Stop(); // Останавливаем таймер чтобы он не вызвался второй раз через секунду.
            Thread.Sleep(5000); // Симуляция работы
            timer.Start();
}

As you can see, this solution is shit code for two reasons:
1. System.Timers.Timer is a Windows Forms component, and I'm writing a framework. It turns out ugly.
2. Before each return, you have to start a timer and also inside each catch.
Please advise the correct solution.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
Ilya, 2019-11-16
@PickGG

I use this solution, the timer waits until the work is finished. In fact, I just turn it off while the job is running, and after completion or exception, I start it again.

public class TestWorker
{
  private readonly Timer _timer;
  public TestWorker()   
  {
    _timer = new Timer(
      Callback, 
      null, 
      TimeSpan.FromSeconds(1),          
      TimeSpan.Zero);
  }

  private void Callback(object state)
  {
    try
    {
      //work imitation
      Thread.Sleep(5000);
    }
    finally
    {
      _timer.Change(
        TimeSpan.FromSeconds(1),    
        TimeSpan.Zero);
    }
  }
}

F
freeExec, 2019-11-16
@freeExec

This is how you separate the timer and payload. And in the timer you check if the old one is still working, then you don’t start the new one.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question