10

I am working with async-await and tasks, but I can't understand the one thing:

Is async task executes in separate thread?

As msdn says (Asynchronous programming):

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread.

But in the remarks in description of ThreadPool class (ThreadPool Class):

Examples of operations that use thread pool threads include the following:

When you create a Task or Task object to perform some task asynchronously, by default the task is scheduled to run on a thread pool thread.

So, now I don't understand if async task uses separate thread. Explain me please. Thanks.

Roman
  • 11,966
  • 10
  • 38
  • 47
  • There are two kinds of tasks: Delegate Tasks (which execute code) and Promise Tasks (which represent a future event). Only Delegate Tasks actually *run*, and they may or may not run on the thread pool. More [on my blog](http://blog.stephencleary.com/2014/04/a-tour-of-task-part-0-overview.html). – Stephen Cleary May 17 '16 at 14:59

3 Answers3

12

A Task does not necessarily represent an extra thread.

If you await a Task, you return the control flow to the caller of your method until "someone" sets the Task as completed.

If you start a Task via Task.Run() or Task.Factory.StartNew(), then the action you pass to these calls is executed on another thread (not a new one, but one from the ThreadPool).

René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • 1
    As a matter of fact, it never creates a new Thread to run a task it always uses one taken from ThreadPool and on oversubscription cases - The CLR avoids oversubscription in the thread pool by queuing tasks and throttling their startup. – Karolis Kajenas May 17 '16 at 14:36
  • 1
    @Carl thank you for the correction, updated my answer. – René Vogt May 17 '16 at 14:39
  • Suppose the code (main thread) calls await asynctask1, and assume asynctask1 has some sync code and an await asynctask2, then in that case the control will not go to main thread immediatelt after await asynctask1. But when the asynctask2 is awaited. Have I got this concept correct? – variable Jul 24 '21 at 19:03
8

To put it in a simple term Task can run on a different Thread as well as it can run on the caller Thread. Task will take a Thread from a ThreadPool ONLY when caller Thread does not have resources to run another Task. Task will be ran on caller Thread when it has enough resources to run another Task (idle mode).

Compared to a thread, a Task is a higher-level abstraction—it represents a concurrent operation that may or may not be backed by a thread. Tasks are compositional (you can chain them together through the use of continuations). They can use the thread pool to lessen startup latency, and with a TaskCompletionSource, they can leverage a callback approach that avoid threads altogether while waiting on I/O-bound operations.

Source: page 565 "C# 5.0 in a Nutshell" by Joseph Albahari, Ben Albahari.

Karolis Kajenas
  • 1,523
  • 1
  • 15
  • 23
  • That explanation is wrong. "Thread load," whatever that is, does not determine if a new task will be executed on the current or another thread. – GSerg May 17 '16 at 14:11
  • @Gserg Could you provide source which disapproves that? – Karolis Kajenas May 17 '16 at 14:13
  • The answers to this questions, to the questions linked to from this question (http://stackoverflow.com/q/13429294/11683, http://stackoverflow.com/q/17661428/11683), and the resources linked to from there. – GSerg May 17 '16 at 14:19
  • @GSerg please review updated answer. Quote source: "C# 5.0 a Nutshell" page 565. – Karolis Kajenas May 17 '16 at 14:28
  • The quote is very correct. If the text above it is your interpretation of what the quote says, you might have misunderstood it. – GSerg May 17 '16 at 14:55
  • @GSerg I do agree that term load was not the best for the case, yes (I have replaced it). But quote clearly states that it "may not be backed by a thread". Could you please elaborate on which part I may have misinterpreted and as well explain your understanding of it. – Karolis Kajenas May 17 '16 at 15:05
  • `a concurrent operation that may or may not be backed by a thread` means `an async operation may be implemented as a separate thread (i.e. backed by a separate thread), or it may be implemented using the calling thread (i.e. backed by the current thread)`. Apparently you understood `may not be backed by` as `when there is not enough support for it`, which is not the case. The quote simply states that an async task is not really concerned with threads, and depending on various factors it may or may not be launched on a separate thread. – GSerg May 17 '16 at 15:36
  • @GSerg That is the very first sentence of my answer which states exactly the same thing. Quote: "To put it in a simple term Task can run on a different Thread as well as it can run on the caller Thread." – Karolis Kajenas May 17 '16 at 16:36
  • Yes, and that sentence is correct. The next two sentences are wrong. – GSerg May 17 '16 at 18:05
7

async/await work on Tasks (well not exactly, it works on "awaitables", but just saying "Task" is close enough for this discussion).

Tasks represent "A unit of work that will be completed at a later time". That unit of work could be a new thread from the thread pool started via Task.Run(, it could be a system IO call like DbDataReader.ReadAsync(), or it could be triggered by a event from a TaskCompletionSource.

I recommend reading Stephen Cleary's async and await intro to learn more about the

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431