在c# 4.0中,我们在System.Threading.Tasks命名空间中有Task。线程和任务之间的真正区别是什么?我做了一些样本程序(从MSDN的帮助),为了我自己的学习

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

但有很多怀疑,因为想法不是很清楚。

我最初在Stackoverflow中搜索了类似类型的问题,但可能是这个问题的标题我无法得到相同的答案。如果有人知道之前贴在这里的相同类型的问题,请提供链接的参考。


当前回答

您可以使用Task指定要做什么,然后将该任务附加到线程中。这样任务就会在新创建的线程中执行,而不是在GUI线程上。

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.

**请注意Action是一个委托。

其他回答

我通常使用任务与Winforms和简单的后台工作人员交互,使其不冻结UI。下面是我喜欢使用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();
}

区别在于你不需要使用MethodInvoker和更短的代码。

任务是你想要完成的事情。

线程是执行该任务的许多可能的工作线程之一。

在. net 4.0术语中,Task表示异步操作。线程通过将工作分解成块并分配给单独的线程来完成该操作。

Task可以被看作是一种异步和并行执行某项任务的简便方法。

通常一个任务是所有你需要的,我不记得如果我曾经使用线程除了实验。

你可以用线程(付出很多努力)完成和用任务一样的事情。

线程

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

默认情况下,任务将使用Threadpool,这节省了资源,因为创建线程的开销很大。您可以将Task视为线程的更高级别抽象。

正如本文所指出的,Task在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.

在计算机科学术语中,任务是一个未来或承诺。(有些人用这两个词的同义词,有些人用不同的方式,没有人能对一个精确的定义达成一致。)基本上,Task<T>“承诺”会给你一个T,但不是现在,亲爱的,我有点忙,你为什么不待会儿再来?

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!)

除以上几点外,最好了解以下几点:

任务默认为后台任务。你不能有前台任务。另一方面,线程可以是后台的,也可以是前台的(使用IsBackground属性来改变行为)。 在线程池中创建的任务可以回收线程,从而节省资源。所以在大多数情况下,任务应该是你的默认选择。 如果操作很快,使用任务而不是线程要好得多。对于长时间运行的操作,任务没有提供比线程更多的优势。