DEV Community

loading...

Beware of how you create a Task

G.L Solaria
Windows by day, Linux by night
・2 min read

I have made this mistake a few times now so I thought I would try to cement it in to my memory by writing a post about it!

I had a case where I wanted to separate the task creation from the task run in one of my previous posts and I used code that looked like this ...

static async Task FireAndForget()
{
  // Warning: Do not do this ...
  Task task = new Task(async () =>
  {
    Console.WriteLine("Going to sleep ...");
    await Task.Delay(1000);
    Console.WriteLine("... Woke up");
  });

  task.Start();

  await task;
}

static async Task Main(string[] args)
{
  await FireAndForget();

  Console.WriteLine("Run complete");

  Console.ReadKey();
}
Enter fullscreen mode Exit fullscreen mode
Going to sleep ...
Run complete
... Woke up
Enter fullscreen mode Exit fullscreen mode

Initially I expected the "... Woke up" message to be output before the "Run complete" message. But then I remembered that the signature for the Task constructor is ...

public Task (Action action);
Enter fullscreen mode Exit fullscreen mode

This means I am awaiting a task that is executing an action. Action returns an async void so when the action is executed, it will not actually await the completion of the Task.Delay.

What I actually needed to use was Func that returns a Task ...

static async Task FireAndAwaitAsync()
{
  var funcTask = new Func<Task>(async () =>
  {
    Console.WriteLine("Going to sleep ...");
    await Task.Delay(1000);
    Console.WriteLine("... Woke up");
  });

  Task task = funcTask.Invoke();

  await task;
}

static async Task Main(string[] args)
{
  await FireAndAwaitAsync();

  Console.WriteLine($"{DateTime.Now} Run complete");

  Console.ReadKey();
}
Enter fullscreen mode Exit fullscreen mode

Which outputs ...

Going to sleep ...
... Woke up
Run complete
Enter fullscreen mode Exit fullscreen mode

Generally you don't need to separate out task creation from running the task so this is not usually an issue. Now to go back over my previous posts and make sure I fix this error.

Discussion (1)

Collapse
aliki212 profile image
AlikiP

Great post!I wish all devs would post this way!Thank you for the insight, async is tough to comprehend!