What is the difference between task and thread?
Asked Answered
M

8

442

In C# 4.0, we have Task in the System.Threading.Tasks namespace. What is the true difference between Thread and Task. I did some sample program(help taken from MSDN) for my own sake of learning with

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

but have many doubts as the idea is not so clear.

I have initially searched in Stackoverflow for a similar type of question but may be with this question title I was not able to get the same. If anyone knows about the same type of question being posted here earlier, kindly give the reference of the link.

Minutiae answered 9/11, 2010 at 3:14 Comment(1)
threads run tasksNepheline
M
360

A task is something you want done.

A thread is one of the many possible workers which performs that task.

In .NET 4.0 terms, a Task represents an asynchronous operation. Thread(s) are used to complete that operation by breaking the work up into chunks and assigning to separate threads.

Memorandum answered 9/11, 2010 at 3:15 Comment(2)
Could you provide a rudimentary example of threads working to complete a task? I don't know if the threads are doing work that are independant between each others or do they do some teamwork calculation?Tobias
Both scenarios are possible: in an optimal situation, threads do independent work without the need to synchonise with other threads. In practice, locks are used to coordinate threads.Memorandum
T
538

In computer science terms, a Task is a future or a promise. (Some people use those two terms synonymously, some use them differently, nobody can agree on a precise definition.) Basically, a Task<T> "promises" to return you a T, but not right now honey, I'm kinda busy, why don't you come back later?

A Thread is a way of fulfilling that promise. But not every Task needs a brand-new Thread. (In fact, creating a thread is often undesirable, because doing so is much more expensive than re-using an existing thread from the thread pool. More on that in a moment.) If the value you are waiting for comes from the filesystem or a database or the network, then there is no need for a thread to sit around and wait for the data when it can be servicing other requests. Instead, the Task might register a callback to receive the value(s) when they're ready.

In particular, the Task does not say why it is that it takes such a long time to return the value. It might be that it takes a long time to compute, or it might be that it takes a long time to fetch. Only in the former case would you use a Thread to run a Task. (In .NET, threads are freaking expensive, so you generally want to avoid them as much as possible and really only use them if you want to run multiple heavy computations on multiple CPUs. For example, in Windows, a thread weighs 12 KiByte (I think), in Linux, a thread weighs as little as 4 KiByte, in Erlang/BEAM even just 400 Byte. In .NET, it's 1 MiByte!)

Tend answered 9/11, 2010 at 3:47 Comment(15)
Interestingly in the early preview releases of TPL (Task Parallel Library) there was Task and Future<T>. Future<T> was then renamed to Task<T>. :)Surcingle
How did you calculate 1 MB for .NET?Inept
@DanVallejo: That number was mentioned in an interview with the TPL design team. I can't tell you who said it or which interview it was, I watched that years ago.Affright
"not every Task needs a Thread" - i am not a .Net guy. Just got a doubt on this statement. To fetch the data from file-system or database, we need to execute an API. And a thread is only vehicle to do that. Isn't it ?Mellisamellisent
@RIPUNJAYTRIPATHI Sure, but it doesn't need to be another thread, it could be the thread that requested the work in the first place.Apposite
now that you brign up something about call back, can you expline this too?Misjoinder
Regarding "Not every task needs a thread", it does not make sense to me. All tasks runs in the context of some thread including a callback.Matchmaker
@RohitSharma, I think what he means is that "not every task needs a separate thread".Younts
@DanVallejo The size is mentioned at the beginning of the 2nd video posted by Navan hereLockhart
@JörgWMittag When you mean "ready" does this mean when the scheduler is ready?Politicize
So by default a task won't be assigned to a new thread. you need to do that explicitly. Is that correct?Filemon
The default stack reservation size for a thread is 1MB as stated here: msdn.microsoft.com/en-us/library/windows/desktop/…Midi
.NET just uses Windows threads on Windows, so the size is the same - by default, usually 1 MiB of virtual memory for both. Physical memory is used as needed in page-sized chunks (usually 64 kiB), the same with native code. The minimum thread stack size depends on the OS - 256 kiB for Vista, for example. On x86 Linux, the default is usually 2 MiB - again, allocated in page-sized chunks. (simplification) Erlang only uses one system thread per process, those 400 bytes refer to something similar to .NETs Task.Gaylordgaylussac
@RohitSharma What thread is used by Task.FromResult("Hi!")?Gaylordgaylussac
"Basically, a Task<T> "promises" to return you a T, but not right now honey, I'm kinda busy, why don't you come back later?" => best definition I ever found.Susannasusannah
M
360

A task is something you want done.

A thread is one of the many possible workers which performs that task.

In .NET 4.0 terms, a Task represents an asynchronous operation. Thread(s) are used to complete that operation by breaking the work up into chunks and assigning to separate threads.

Memorandum answered 9/11, 2010 at 3:15 Comment(2)
Could you provide a rudimentary example of threads working to complete a task? I don't know if the threads are doing work that are independant between each others or do they do some teamwork calculation?Tobias
Both scenarios are possible: in an optimal situation, threads do independent work without the need to synchonise with other threads. In practice, locks are used to coordinate threads.Memorandum
D
80

Thread

The bare metal thing, you probably don't need to use it, you probably can use a LongRunning task and take the benefits from the TPL - Task Parallel Library, included in .NET Framework 4 (february, 2002) and above (also .NET Core).

Tasks

Abstraction above the Threads. It uses the thread pool (unless you specify the task as a LongRunning operation, if so, a new thread is created under the hood for you).

Thread Pool

As the name suggests: a pool of threads. This is the .NET framework handling a limited number of threads for you. Why? Because opening 100 threads to execute expensive CPU operations on a Processor with just 8 cores definitely is not a good idea. The framework will maintain this pool for you, reusing the threads (not creating/killing them at each operation), and executing some of them in parallel, in a way that your CPU will not burn.

OK, but when to use each one?

In resume: always use tasks.

Task is an abstraction, so it is a lot easier to use. I advise you to always try to use tasks and if you face some problem that makes you need to handle a thread by yourself (probably 1% of the time) then use threads.

BUT be aware that:

  • I/O Bound: For I/O bound operations (database calls, read/write files, APIs calls, etc) avoid using normal tasks, use LongRunning tasks (or threads if you need to). Because using tasks would lead you to a thread pool with a few threads busy and a lot of other tasks waiting for its turn to take the pool.
  • CPU Bound: For CPU bound operations just use the normal tasks (that internally will use the thread pool) and be happy.
Dime answered 14/7, 2017 at 23:2 Comment(3)
slight correction, a Thread isn't a "bare-metal thing". it is implemented by the OS, most implementations relay on features of the CPU and CS, but they are not implemented by the hardware.Bot
i am not enterly sure the information about I/O Bound is correct. it doesn't matter how many tasks have been created that access external services like db's and api's. The task itself in those cases is stored a callback method in memory. When the response comes back from the DB, the CPU will trigger a system interrupt which, in bigger words, will ask the IO thread pool (this a OS thread pool) to take the response and "anounce" the task, which is in memory at this point, that it's data has arrived, and it can continue it's execution from where it was left. Don't use Threads for ext services.Anastatius
I don't perfectly understand the last part of @VladSandu's comment, but I have the same sentiment about using a separate thread(whether it is LongRunning tasks) for I/O Bound work. Don't I/O bound tasks use callback rather than holding a thread for it to wait for the result?Whallon
A
11

In addition to above points, it would be good to know that:

  1. A task is by default a background task. You cannot have a foreground task. On the other hand a thread can be background or foreground (Use IsBackground property to change the behavior).
  2. Tasks created in thread pool recycle the threads which helps save resources. So in most cases tasks should be your default choice.
  3. If the operations are quick, it is much better to use a task instead of thread. For long running operations, tasks do not provide much advantages over threads.
Apportion answered 1/8, 2017 at 23:37 Comment(0)
R
9

A Task can be seen as a convenient and easy way to execute something asynchronously and in parallel.

Normally a Task is all you need, I cannot remember if I have ever used a thread for anything other than experimentation.

You can accomplish the same thing, with a thread (with lots of effort) as you can with a task.

Thread

int result = 0;
Thread thread = new System.Threading.Thread(() => { 
    result = 1; 
});
thread.Start();
thread.Join();
Console.WriteLine(result); //is 1

Task

int result = await Task.Run(() => {
    return 1; 
});
Console.WriteLine(result); //is 1

A task will by default use the Threadpool, which saves resources as creating threads can be expensive. You can see a Task as a higher level abstraction upon threads.

As this article points out, Task provides the following powerful features over Thread.

  • Tasks are tuned for leveraging multicore processors.

  • If the system has multiple Tasks then it makes use of the CLR thread pool internally, and so does not have the overhead associated with creating a dedicated thread using the Thread. Also reduces the context switching time among multiple threads.

  • Task can return a result. There is no direct mechanism to return the result from thread.

  • Wait on a set of Tasks, without a signaling construct.

  • We can chain Tasks together to execute one after the other.

  • Establish a parent/child relationship when one task is started from another task.

  • A child Task Exception can propagate to parent task.

  • Tasks support cancellation through the use of cancellation tokens.

  • Asynchronous implementation is easy in Task, using async and await keywords.

Recognizee answered 3/11, 2019 at 23:49 Comment(1)
Thank you for the summary. But I think most of the convenience-related features mentioned above would use resources auto-generated by the compiler at the end of the day just like we have to manually code using a thread. For instance, waiting on a set of Tasks would internally need a signaling construct auto-coded(or implemented) by the compiler, and also a Task returning a result would need an object to bind the result to.Whallon
K
7

I usually use Task to interact with Winforms and simple background worker to make it not freeze the UI. Here is an example of when I prefer using Task.

private async void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    await Task.Run(() => {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
    })
    buttonDownload.Enabled = true;
}

VS

private void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    Thread t = new Thread(() =>
    {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
        this.Invoke((MethodInvoker)delegate()
        {
            buttonDownload.Enabled = true;
        });
    });
    t.IsBackground = true;
    t.Start();
}

the difference is you don't need to use MethodInvoker and shorter code.

Koball answered 22/7, 2018 at 9:53 Comment(0)
J
6

You can use Task to specify what you want to do then attach that Task with a Thread. so that Task would be executed in that newly made Thread rather than on the GUI thread.

Use Task with the TaskFactory.StartNew(Action action). In here you execute a delegate so if you didn't use any thread it would be executed in the same thread (GUI thread). If you mention a thread you can execute this Task in a different thread. This is an unnecessary work cause you can directly execute the delegate or attach that delegate to a thread and execute that delegate in that thread. So don't use it. it's just unnecessary. If you intend to optimize your software this is a good candidate to be removed.

**Please note that the Action is a delegate.

Jackknife answered 19/7, 2012 at 23:52 Comment(0)
P
4

Task is like an operation that you want to perform. Thread helps to manage those operation through multiple process nodes. Task is a lightweight option as Threading can lead to complex code management.
I suggest you read from MSDN (best in world) always

Task

Thread

Polymerism answered 27/3, 2017 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.