Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wait for a Task that calls an async method to complete without blocking thread

I am trying to execute 2 tasks in succession, but the second task is running before the first task has completely finished because it is awaitable

var task1 = new Task(async () =>
{
    Trace.WriteLine("before delay");
    await Task.Delay(1000);
    Trace.WriteLine("after delay");
});

task1.ContinueWith(task => Trace.WriteLine("continued"));

task1.Start();
task1.Wait();

I would like to elicit the output

before delay 
after delay 
continued

but I get

before delay
continued

Is there a way to block task1 without holding up the thread?

like image 838
benthemos Avatar asked Sep 08 '15 12:09

benthemos


2 Answers

Your async lambda returns early making new Task think the task is done. It returns at the first await. The task constructor is off limits! Don't use it (almost never).

It's existence is basically a design bug in the framework. Unstarted tasks should not even exist and the Start method should be deleted. We have TaskCompletionSource for that.

Use Task.Run(async () => .... Task.Run has special support for Task returning functions.

like image 177
usr Avatar answered Oct 19 '22 06:10

usr


To complement @usr's answer, I think it's worth showing how to make your existing code work, with these minor changes:

Task<Task> task1 = new Task<Task>(new Func<Task>(async () =>
{
    Trace.WriteLine("before delay");
    await Task.Delay(1000);
    Trace.WriteLine("after delay");
}));

var task2 = task1.Unwrap();

var task3 = task2.ContinueWith(task => Trace.WriteLine("continued"));

task1.Start();
task3.Wait();

Hope this helps to understand the actual task workflow better. Task.Unwrap can be a power tool if used properly.

That said, you indeed should not need to create a Task object via its constructor. To learn more, check TPL's Stephen Toub blog posts:

  • Task.Factory.StartNew vs new Task(...).Start
  • Task.Run vs Task.Factory.StartNew.
  • Processing Sequences of Asynchronous Operations with Tasks
like image 27
noseratio Avatar answered Oct 19 '22 07:10

noseratio