What is the difference between task and thread?

后端 未结 8 1588
庸人自扰
庸人自扰 2020-11-22 02:45

In C# 4.0, we have Task in the System.Threading.Tasks namespace. What is the true difference between Thread and Task. I did s

相关标签:
8条回答
  • 2020-11-22 03:08

    In computer science terms, a Task is a future or a promise. (Some people use those two terms synomymously, 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 threadpool. 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 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!)

    0 讨论(0)
  • 2020-11-22 03:15

    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.

    0 讨论(0)
  • 2020-11-22 03:18

    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.

    0 讨论(0)
  • 2020-11-22 03:21

    I usually use Task to interact with Winforms and simple background worker to make it not freezing the UI. here an example 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.

    0 讨论(0)
  • 2020-11-22 03:25

    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. 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 another 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.
    0 讨论(0)
  • 2020-11-22 03:25

    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 something else than experimentation.

    You can accomplish the same 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 following powerful features over thread.

    • Tasks are tuned for leveraging multicores processors.

    • If system has multiple tasks then it make use of the CLR thread pool internally, and so do not have the overhead associated with creating a dedicated thread using the Thread. Also reduce 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.

    • Child task exception can propagate to parent task.

    • Task support cancellation through the use of cancellation tokens.

    • Asynchronous implementation is easy in task, using’ async’ and ‘await’ keywords.

    0 讨论(0)
提交回复
热议问题