locked
Difference Between Threads and Tasks

    Question

  • Hi, what is the difference between threads and tasks in programming. For example, the Async CTP for VS uses tasks instead of threads to do asynchronous methods. What is the difference??

    Thanks!

     


    - Nevin Janzen

     


    Sunday, January 08, 2012 9:47 PM

Answers

  • re: "Threads can only have one task running at a time"

    That's almost true.  It's true that a single thread can't be running two tasks concurrently.  However, if a task itself processes another task (e.g. if Task t1 calls t2.Wait() and Task t2 hasn't started running yet such that it can be run as part of the Wait call rather than the Wait call simply blocking waiting for some other thread to run t2), then in a sense that thread is processing multiple tasks.  That's an optimization, though... at a high-level, you can think of the answer to your question being "yes".

    re: "a task can have multiple processes happening at the same time within them, specifically asynchronous methods"

    I don't understand what this means.  A Windows process has one or more threads, and a thread executes tasks... a task doesn't "have" a process.  Now, if what you mean is whether a task can be doing more than one thing at a time, the answer is no.  A Task is just a data structure that represents the eventual completion of some operation; it's also optionally contains a delegate to run as that operation.  In the case where it contains a delegate (e.g. you created the task with Task.Run(someDelegate)), that Task is 1:1 tied with that delegate's execution.  In the case where the Task is used to represent some arbitrary operation, it's up to the implementation of that operation when the task should complete.  For example, if you create a Task using TaskCompletionSource, that Task will complete when you call SetResult, SetException, or SetCanceled on that TaskCompletionSource, and when you call those methods is entirely up to you.  You could have launched a single asynchronous operation and then call one of those methods when the operation completes, or you could have launched 10 asynchronous operations and then call one of those methods when they all complete... that's entirely up to you. The Task isn't running anything... all it knows is that it'll get one call to mark it as completed, and it's up to you when to do that based on what you want the task to represent.  In the case of an async method (one that's marked with the async keyword), the same truth holds... it's just that the compiler will generate code to call one of those SetResult/Exception/Canceled methods when the end of the async method is reached... you can do whatever you want in the body of that method, including launching multiple async operations and waiting for them all, and the task will only be completed once the method body has completed.

    re: "let's say I await this async function: FnAsync1() and then right after that I await FnAsync2(); do they both execute their code concurrently?"

    If you write:

    await FnAsync1();
    await FnAsync2();

    they will not run concurrently... the await keyword is like saying "do not progress until the task handed to me has completed", so you won't even execute FnAsync2() until the task returned from FnAsync1() has completed.  In contrast, if you wrote:

    var t1 = FnAsync1();
    var t2 = FnAsync2();
    await Task.WhenAll(t1, t2); // or "await t1; await t2;"

    then they might run concurrently.

    re: "Can FnAsync2() return before FnAsync1() even though FnAsync1() was called first?"

    In the case of "await FnAsync1(); await FnAsync2();", FnAsync2() won't even be invoked until the task returned from FnAsync1() has completed, so there's no chance FnAsync2() could finish first.  In the case where you first invoke both FnAsync1() and FnAsync2() and then only after invoking both do you await their returned tasks, it's certainly possible that the Task from FnAsync2() could complete first.

    re: "can I have an async method return a Boolean or any other type I want?"

    An async method can return a Task<T>, where the T is anything you would be able to return from a regular synchronous method.

    Monday, January 16, 2012 4:32 PM

All replies

  • Each thread is a different executor of code, with its own call stack. Threads allow multiprocessing, but within the same actual process.

    Tasks are independent operations that have a definite beginning and end. Tasks either have some code to run (i.e., a delegate), or they do not.

    Tasks without delegates are not actually executed; they're just completed. These often represent I/O-bound operations. For example, a task may represent reading a file from a web site - there is no real code to run, just a notification when it is completed.

    Tasks with a delegate must be run by a thread. Many tasks are queued to the thread pool (e.g., TaskEx.Run will create a task that will run on a thread pool thread). Other tasks have certain requirements and have to be run by specific threads - e.g., if a task updates UI elements, it needs to be run on the UI thread.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible

    Monday, January 09, 2012 5:17 PM
  • Thank you very much for your response! So, can multiple tasks run asynchronously on a single thread, or can you have only one task executing side-by-side with the normal execution of your code?

     

    To help clarify what I mean, consider this: let's say I am writing a programming language that supports asynchronous functions, and this is the declaration of the function:

     

    async FnAsync(string s) as bool
    {
        /* some code that writes to a file indicated in the 
            string and then returns a Boolean representing 
            if it was done successfully */
    }
    
    

     

    I want to execute the code in the function asynchronously when I call it like this:

     

    bool b = await FnAsync("C:\Dir\File.txt");
    
    

     

     

    I don't want to use multiple threads, so a good option would be to use tasks, right? Or, can you think of something else I could do? I want asynchronous functions to be flexible and just like normal functions except they run asynchronously.

    Also, I thought I would just let you know that I know nothing about delegates.

    Thanks!

     


    - Nevin Janzen

     

    Monday, January 09, 2012 7:17 PM
  • A thread can only run one thing at a time. So only one task per thread can be run at a time.

    Asynchronous methods, however, may be concurrent. It is possible for one thread to start several asynchronous methods, any of which may complete on that same thread.

    For your example, you can use asynchronous methods.

           -Steve

    P.S. Delegates are a fundamental knowledge in C#. I recommend going through a copy of C# in Depth at the earliest convenience.


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible
    Tuesday, January 10, 2012 3:40 AM
  • Thank you very much for your response.

    So, am I correct when I say this: "Threads can only have one task running at one time, but a task can have multiple processes happening at the same time within them, specifically asynchronous methods."?

    Also: let's say I await this async function: FnAsync1() and then right after that I await FnAsync2(); do they both execute their code concurrently? Can FnAsync2() return before FnAsync1() even though FnAsync1() was called first? They return whenever they finish, right?

    One more thing: can I have an async method return a Boolean or any other type I want?

    Thanks!

    P.S.  Please try to give an answer for every question mark you see. Thank you very much!! You are most appreciated!

     


    Nevin Janzen -- If this post answers your question, please click Propose As Answer. If this post is helpful, please click Vote As Helpful. Thanks!
    Tuesday, January 10, 2012 4:14 AM
  • re: "Threads can only have one task running at a time"

    That's almost true.  It's true that a single thread can't be running two tasks concurrently.  However, if a task itself processes another task (e.g. if Task t1 calls t2.Wait() and Task t2 hasn't started running yet such that it can be run as part of the Wait call rather than the Wait call simply blocking waiting for some other thread to run t2), then in a sense that thread is processing multiple tasks.  That's an optimization, though... at a high-level, you can think of the answer to your question being "yes".

    re: "a task can have multiple processes happening at the same time within them, specifically asynchronous methods"

    I don't understand what this means.  A Windows process has one or more threads, and a thread executes tasks... a task doesn't "have" a process.  Now, if what you mean is whether a task can be doing more than one thing at a time, the answer is no.  A Task is just a data structure that represents the eventual completion of some operation; it's also optionally contains a delegate to run as that operation.  In the case where it contains a delegate (e.g. you created the task with Task.Run(someDelegate)), that Task is 1:1 tied with that delegate's execution.  In the case where the Task is used to represent some arbitrary operation, it's up to the implementation of that operation when the task should complete.  For example, if you create a Task using TaskCompletionSource, that Task will complete when you call SetResult, SetException, or SetCanceled on that TaskCompletionSource, and when you call those methods is entirely up to you.  You could have launched a single asynchronous operation and then call one of those methods when the operation completes, or you could have launched 10 asynchronous operations and then call one of those methods when they all complete... that's entirely up to you. The Task isn't running anything... all it knows is that it'll get one call to mark it as completed, and it's up to you when to do that based on what you want the task to represent.  In the case of an async method (one that's marked with the async keyword), the same truth holds... it's just that the compiler will generate code to call one of those SetResult/Exception/Canceled methods when the end of the async method is reached... you can do whatever you want in the body of that method, including launching multiple async operations and waiting for them all, and the task will only be completed once the method body has completed.

    re: "let's say I await this async function: FnAsync1() and then right after that I await FnAsync2(); do they both execute their code concurrently?"

    If you write:

    await FnAsync1();
    await FnAsync2();

    they will not run concurrently... the await keyword is like saying "do not progress until the task handed to me has completed", so you won't even execute FnAsync2() until the task returned from FnAsync1() has completed.  In contrast, if you wrote:

    var t1 = FnAsync1();
    var t2 = FnAsync2();
    await Task.WhenAll(t1, t2); // or "await t1; await t2;"

    then they might run concurrently.

    re: "Can FnAsync2() return before FnAsync1() even though FnAsync1() was called first?"

    In the case of "await FnAsync1(); await FnAsync2();", FnAsync2() won't even be invoked until the task returned from FnAsync1() has completed, so there's no chance FnAsync2() could finish first.  In the case where you first invoke both FnAsync1() and FnAsync2() and then only after invoking both do you await their returned tasks, it's certainly possible that the Task from FnAsync2() could complete first.

    re: "can I have an async method return a Boolean or any other type I want?"

    An async method can return a Task<T>, where the T is anything you would be able to return from a regular synchronous method.

    Monday, January 16, 2012 4:32 PM
  • Thank you very much for your clarity, content, and good explanations. I love it when someone breaks my posts down into segments and answers all my questions. I up-voted and marked your reply as the answer; you have earned it. Thank you so much.

    Keep up the great work!

     


    Nevin Janzen  -  If this post answers your question, please click Propose As Answer. If this post is helpful, please click Vote As Helpful. Thanks!
    Monday, January 16, 2012 5:45 PM