In C# I have the following two simple examples:
[Test] public void TestWait() { var t = Task.Factory.StartNew(() => { Console.WriteLine("Start"); Task.Delay(5000).Wait(); Console.WriteLine("Done"); }); t.Wait(); Console.WriteLine("All done"); } [Test] public void TestAwait() { var t = Task.Factory.StartNew(async () => { Console.WriteLine("Start"); await Task.Delay(5000); Console.WriteLine("Done"); }); t.Wait(); Console.WriteLine("All done"); }
The first example creates a task that prints "Start", waits 5 seconds prints "Done" and then ends the task. I wait for the task to finish and then print "All done". When I run the test it does as expected.
The second test should have the same behavior, except that the waiting inside the Task should be non-blocking due to the use of async and await. But this test just prints "Start" and then immediately "All done" and "Done" is never printed.
I do not know why I get this behavior :S Any help would be appreciated very much :)
'Wait' means to pass the time until an anticipated event occurs, whereas 'await' means to wait for something with a hope.
Note that since the task that calls the Delay method executes asynchronously, the parent task must wait for it to complete by using the await keyword.
By using Task. Delay , now when we wait to retry the request, the thread is release back to its caller or to thread pool. Another potential scenario is when we want to do something but within a specific time frame. If the task is not finished by that time, We're going to return null.
await Task. Delay(1000) doesn't block the thread, unlike Task. Delay(1000).
The second test has two nested tasks and you are waiting for the outermost one, to fix this you must use t.Result.Wait()
. t.Result
gets the inner task.
The second method is roughly equivalent of this:
public void TestAwait() { var t = Task.Factory.StartNew(() => { Console.WriteLine("Start"); return Task.Factory.StartNew(() => { Task.Delay(5000).Wait(); Console.WriteLine("Done"); }); }); t.Wait(); Console.WriteLine("All done"); }
By calling t.Wait()
you are waiting for outermost task which returns immediately.
The ultimately 'correct' way to handle this scenario is to forgo using Wait
at all and just use await
. Wait
can cause deadlock issues once you attached a UI to your async code.
[Test] public async Task TestCorrect() //note the return type of Task. This is required to get the async test 'waitable' by the framework { await Task.Factory.StartNew(async () => { Console.WriteLine("Start"); await Task.Delay(5000); Console.WriteLine("Done"); }).Unwrap(); //Note the call to Unwrap. This automatically attempts to find the most Inner `Task` in the return type. Console.WriteLine("All done"); }
Even better just use Task.Run
to kick off your asynchronous operation:
[TestMethod] public async Task TestCorrect() { await Task.Run(async () => //Task.Run automatically unwraps nested Task types! { Console.WriteLine("Start"); await Task.Delay(5000); Console.WriteLine("Done"); }); Console.WriteLine("All done"); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With