Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay then execute Task

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?

like image 322
David Avatar asked Oct 31 '13 10:10

David


People also ask

What is task delay?

The Delay method is typically used to delay the operation of all or part of a task for a specified time interval. Most commonly, the time delay is introduced: At the beginning of the task, as the following example shows.

Does task delay block?

Task. Delay() is asynchronous. It doesn't block the current thread. You can still do other operations within current thread.

Does task delay create a new thread?

Task. Delay does not create new Thread, but still may be heavy, and no guaranties on order of execution or being precise about deadlines.

Does task delay block thread?

Delay(1000) doesn't block the thread, unlike Task. Delay(1000).


2 Answers

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.

like image 51
svick Avatar answered Sep 21 '22 10:09

svick


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");     } } 
like image 30
Attila Avatar answered Sep 19 '22 10:09

Attila