Delay then execute Task

David picture David · Oct 31, 2013 · Viewed 63.1k times · Source

Quick question, I want to wait a second before launching an async task without a return value.
Is this the right way to do it?

Task.Delay(1000)
    .ContinueWith(t => _mq.Send(message))
    .Start();

What happens to exceptions?

Answer

svick picture svick · Oct 31, 2013

First of all, Start() only works on the (very rare) Tasks that were created using the Task constructor (e.g. new Task(() => _mq.Send(message))). In all other cases, it will throw an exception, because the Task is already started or waiting for another Task.

Now, probably the best way to do this would be to put the code into a separate async method and use await:

async Task SendWithDelay(Message message)
{
    await Task.Delay(1000);
    _mq.Send(message);
}

If you do this, any exception from the Send() method will end up in the returned Task.

If you don't want to do that, using ContinueWith() is a reasonable approach. In that case, exception would be in the Task returned from ContinueWith().

Also, depending on the type of _mq, consider using SendAsync(), if something like that is available.