Why awaiting cold Task does not throw
async-await, asynchronous, c#
Solution
You're trying to start the task returned by the async method - that isn't the cold task that you started out with. Indeed, if you add some diagnostics to your `Task.Run` call, you'll see that an exception is thrown:
System.InvalidOperationException: Start may not be called on a promise-style task.
Here's an example showing what I think you were really trying to do:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Test
{
static void Main(string[] args)
{
// Not using Task.Delay! That would be pointless
Task t1 = new Task(() => Thread.Sleep(1000));
Task t2 = Await(t1);
Console.WriteLine(t2.Status);
Console.WriteLine("Starting original task");
t1.Start();
Console.WriteLine(t2.Status);
t2.Wait();
Console.WriteLine(t2.Status);
}
static async Task Await(Task task)
{
Console.WriteLine("Beginning awaiting");
await task;
Console.WriteLine("Finished awaiting");
}
}
Note the use of `Thread.Sleep` instead of `Task.Delay`; unless you're using the result of `Task.Delay`, it basically does nothing. Using `Thread.Sleep` is emulating real work to be done in the other task.
As for why awaiting an unstarted task doesn't throw an exception - I think that's reasonable, to be honest. It allows for situations like the above to be valid, which may in some cases make life easier. (You may create a lot of tasks before starting them, for example - and you may want to start waiting for them to finish before you start them.)
Problem
I was just experimenting to see what happens when a cold task (i.e. a `Task` which hasn't been started) is awaited. To my surprise the code just hung forever and "Finsihed" is never printed. I would expect that an exception is thrown. ``` public async Task Test1() { var task = new Task(() => Thread.Sleep(1000)); //task.Start(); await task; } void Main() { Test1().Wait(); Console.WriteLine("Finished"); } ``` Then I though perhaps the task can be started from another thread, so I changed the code to: ``` public async Task Test1() { var task = new Task(() => Thread.Sleep(1000)); //task.Start(); await task; Console.WriteLine("Test1 Finished"); } void Main() { var task1 = Test1(); Task.Run(() => { Task.Delay(5000); task1.Start(); }); task1.Wait(); Console.WriteLine("Finished"); } ``` But it is still blocked at `task1.Wait()`. Does anyone know if there is way to start a cold task after it has being awaited? Otherwise it seems there is no point in being able to `await` a cold task, so perhaps the task should either be started when awaited or an exception should be thrown. Update I was awaiting the wrong task, i.e. the outer task returned by `Test1` rather than the one newed inside it. The InvalidOperationException mentioned by @Jon Skeet was being thrown inside `Task.Run` however because the resulting task was not observed, the exception was not thrown on the main thread. Putting a `try/catch` inside `Task.Run` or calling `Wait()` or `Result` on the task returned by `Task.Run` threw the exception on the main console thread.