1

I have a hard time getting my head around this.

I need to execute few methods, each one delayed by an amount of time. So from what I could read, I can use Task.Delay or a Timer as it seems internally, Task.Delay is using a Timer.

So are the two following approach equivalent? If not, what would be the pros and cons of each approach?

What happens to the calling thread for each approach? I really don't want to block the thread. I don't think either of those 2 approaches do though.

1st approach:

public async Task SimulateScenarioAsync()
{
    await Task.Delay(1000).ConfigureAwait(false);
    await FooAsync.ConfigureAwait(false);

    await Task.Delay(2000).ConfigureAwait(false);
    await BarAsync.ConfigureAwait(false);

    await Task.Delay(500).ConfigureAwait(false);
    await StuffAsync.ConfigureAwait(false);
}

2nd approach:

public void SimulateScenario()
{
    var timer = new Timer(new TimerCallback(FooAsync), null, 1000, Timeout.Infinite);
}

public void FooAsync(Object obj)
{
    // do some stuff
    var timer = new Timer(new TimerCallback(BarAsync), null, 2000, Timeout.Infinite);
}

public void BarAsync(Object obj)
{
    // do some stuff
    var timer = new Timer(new TimerCallback(StuffAsync), null, 500, Timeout.Infinite);
}

public void StuffAsync(Object obj)
{
    // do some stuff
}
dyesdyes
  • 1,147
  • 3
  • 24
  • 39
  • 2
    If you already using the TPL, I would go for the `Task.Delay()` – Jeroen van Langen Jun 15 '17 at 09:45
  • Yes I am, and the delayed methods are using it too. – dyesdyes Jun 15 '17 at 09:46
  • Your first approach assumes that the tasks are executed in sequence with delays in between. In general, using timers will allow the tasks to execute completely independently. It is not clear from your question if there are implicit dependencies between your tasks but if there are you probably should use the first approach. If the executing time of a task is non-trivial you also have to consider if that should be factored into shortening the delays. Timers can be better at handling this. – Martin Liversage Jun 15 '17 at 09:57
  • 3
    As you see, first approach is much cleaner and expresses your intention clearly, so use it. As for threads - nothing unusual happens with them. When delay ends - thread from a thread pool is grabbed and continuation executes on it. – Evk Jun 15 '17 at 10:00
  • For the opinion-based tag, I disagree because I also ask for specifics on the thread etc. It so happens that both approaches are kind of equivalent in term of technique. But answering this is part of the question... and this is not opinion-based. – dyesdyes Jun 16 '17 at 12:17

2 Answers2

1

I think that first approach is more readable.

Other than that, I can't see any reason for picking either method. If you wait for 1 second between operations, it doesn't really matter what is the performance of that command for sure it will be at least 1000x faster than your waiting period.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57
-1

This question suggests wrapping it in a single call like this

async Task MyTaskWithDelay()
{
    await Task.Delay(1000);
    MyTask();
}

Comparing the two approaches

This answer says

There are two major differences:

  1. The Task.Delay approach will delay the specified amount of time between cycles, while the DispatcherTimer approach will start a new cycle on the specified cycle time.
  2. Task.Delay is more portable, since it does not depend on a type tied to a specific UI.

And this post says

The Task.Delay will block the thread for the specified time. While DispatcherTimer creates a separate thread for the timer and then return to the original thread after the specified time.

Gareth
  • 913
  • 6
  • 14