Delay then execute Task

C#.NetAsynchronousTask Parallel-Library

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

You can catch any exception thrown in the Task if you Wait for the Task to finish:

Be aware of that your Exception thrown in the Task is going to be the inner one

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Task task = Task.Delay(1000)
                .ContinueWith(t => Program.throwsException());
    
            task.Wait();     
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception:" + ex.Message); // Outputs: Exception:One or more errors occurred.
            Console.WriteLine("Inner exception:" + ex.InnerException.Message); // Outputs: Exception:thrown
        }
        Console.ReadKey();
    
    }
    static void throwsException()
    {
        Console.WriteLine("Method started");
        throw new Exception("thrown");
    }
}

Solution 3 - C#

You will be able to observe any exceptions if you Wait for the task.

> Unhandled exceptions that are thrown by user code that is running > inside a task are propagated back to the joining thread, except in > certain scenarios that are described later in this topic. Exceptions > are propagated when you use one of the static or instance Task.Wait or > Task.Wait methods, and you handle them by enclosing the call > in a try-catch statement.

Excerpt from Exception Handling (Task Parallel Library)

Be careful with timings. Tasks use a scheduler and are not guaranteed to start when your say 'go'. You code will guarantee at least 1000ms delay after telling it to Start but it is not guaranteed to be 1000ms exactly.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavidView Question on Stackoverflow
Solution 1 - C#svickView Answer on Stackoverflow
Solution 2 - C#AttilaView Answer on Stackoverflow
Solution 3 - C#GusdorView Answer on Stackoverflow