40

When does a Task actually start?

public void DoSomething() {
    Task myTask = DoSomethingAsync();

    Task.WaitAll(new[] { myTask }, 2000);
}

public async Task DoSomethingAsync() {
    await SomethingElse();
}

Does it start immediately when initializing it in Task myTask = DoSomethingAsync(); or does it start when you say to wait for it in Task.WaitAll(new[] { myTask }, 2000); ?

TheHvidsten
  • 4,028
  • 3
  • 29
  • 62
  • 3
    This is a big question. Have a look here for starters: http://blog.stephencleary.com/2013/11/there-is-no-thread.html – Matthew Watson Mar 29 '17 at 09:22
  • 1
    Patrick Hofman already has given the correct answer. For your example: `DoSomethingAsync()` will immediatly run as far as possible - which means e.g. up to the first point where it awaits some inner task inside which has not yet finished. Only then it will return and the continuation will get attached. If `DoSomethingAsync()` has dozens of nested await functions inside, where all complete synchronously (e.g. the last one is a `Task.FromResult()`) then `myTask` will be completed before the control is given back to the caller. – Matthias247 Mar 29 '17 at 09:34

1 Answers1

60

Calling an async method returns a hot task, a task that has already been started. So there is no actual code necessary to force it to run.

According MSDN (thanks to Stephen Cleary) the Task-based Asynchronous Pattern (TAP) pattern requires returned tasks to be hot. That means that all tasks, except those created with new Task will be hot.

From the referenced article:

Tasks that are created by the public Task constructors are referred to as cold tasks... All other tasks begin their life cycle in a hot state.

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 2
    "When you call a method that returns a Task without async, it will not be started." sounds a bit confusing to me. Majority of methods that return task without async still return task that is already started, because they start it inside method itself. – Evk Mar 29 '17 at 09:45
  • @Evk 'automatically' > better? – Patrick Hofman Mar 29 '17 at 09:45
  • 2
    The `async` modifier is used by the compiler to build the state machine. Other than the constructors of `Task`/`Task`, any API I can think of returns an hot task. That's what `Task.Run` does. So, what do you mean by "When you call a method that returns a `Task` without `async`, it will not be started automatically."? – Paulo Morgado Mar 29 '17 at 13:07
  • `return new Task ...` for example @PauloMorgado – Patrick Hofman Mar 29 '17 at 13:08