任务和线程有什么区别?
在C#4.0中,我们在System.Threading.Tasks命名空间中有Task
。 Thread
和Task
之间真正的区别是什么? 我做了一些示例程序(来自MSDN的帮助)为我自己学习
Parallel.Invoke Parallel.For Parallel.ForEach
但是这个想法还不是很清楚,所以有很多疑问。
我最初在Stackoverflow中搜索类似的问题,但可能与这个问题标题我不能得到相同的。 如果有人知道前面发布的同类问题,请给出链接的参考。
一个任务是你想做的事情。
线程是执行该任务的许多可能的工作人员之一。
在.NET 4.0中, Task表示一个异步操作。 线程用于完成该操作,将工作分解为块并分配给不同的线程。
在计算机科学方面, Task
是未来或承诺 。 (有些人使用这两个词同义词,有些人使用它们不同,没有人可以同意一个确切的定义。)基本上,一个Task<T>
“承诺”返回给你一个T
,但不是现在亲爱的,我有点忙,你为什么不晚点回来?
Thread
是实现这一承诺的一种方式。 但不是每个Task
需要一个全新的Thread
。 (实际上,创建一个线程通常是不可取的,因为这样做比重用线程池中的现有线程要昂贵得多。)如果你正在等待的值来自文件系统或者数据库或网络,那么当线程可以服务于其他请求时,就不需要线程坐下来等待数据。 相反, Task
可能会注册一个回调,以便在准备好时接收值。
特别是,这个Task
并没有说为什么要花这么长的时间来回报价值。 这可能需要很长时间来计算,或者可能需要很长时间才能获取。 只有在前一种情况下,你会使用一个Thread
来运行一个Task
。 (在.NET中,线程是非常昂贵的,所以你通常希望尽可能地避免它们,如果你想在多个CPU上运行多重计算,真的只用它们。例如,在Windows中,一个线程的重量为12 KiByte我认为),在Linux中,一个线程的重量只有4 KiByte,Erlang / BEAM甚至只有400 Byte,在.NET中是1 MiByte!)
当我们在多个线程上执行的时候,不能保证线程在多个处理器之间是分开的。
Task是管理可并行工作单元的轻量级对象。 它可以用于任何时候你想并行执行的东西。 并行意味着工作分散在多个处理器上以最大化计算速度。 调整任务以利用多核处理器。
任务通过线程提供以下强大的功能。
- 如果系统有多个任务,那么它在内部使用CLR线程池,所以没有使用线程创建专用线程的开销。 还可以减少多个线程之间的上下文切换时间。
- 任务可以返回结果。没有直接的机制从线程返回结果。
-
等待一组任务,没有信令结构。
-
我们可以把任务连在一起,依次执行。
-
当一个任务从另一个任务开始时建立父母/子女关系。
-
子任务异常可以传播给父任务。
-
任务支持通过使用取消令牌取消。
-
使用“async”和“await”关键字,异步实现非常容易。
以下两个来自channel-9的视频将让您更好地理解任务和主题,以及我们应该在哪里使用它们。
http://channel9.msdn.com/blogs/bruceky/how-to-parallelize-your-application-part-2-theads-v-tasks http://channel9.msdn.com/blogs/bruceky/how-to -parallelize-您的应用程序-部分- 3 -使用任务
如果你有更多的时间,那么从这个视频开始
http://channel9.msdn.com/blogs/bruceky/how-to-parallelize-your-application-part-1-why-do-it
您可以使用Task
来指定您想要执行的操作,然后使用Thread
附加该Task
。 因此Task
将在新创建的Thread
执行,而不是在GUI线程中执行。
将Task
与TaskFactory.StartNew(Action action)
一起使用TaskFactory.StartNew(Action action)
。 在这里你执行一个委托,所以如果你没有使用任何线程,它会在同一个线程(GUI线程)中执行。 如果你提到一个线程,你可以在不同的线程中执行这个Task
。 这是不必要的工作,因为您可以直接执行委托或将该委托附加到线程并在该线程中执行该委托。 所以不要使用它。 这只是没有必要的。 如果你打算优化你的软件,这是一个很好的候选人被删除。
**请注意,该Action
是一个delegate
。
线
裸机的东西,你可能不需要使用它,你可能可以使用LongRunning
任务,并从TPL(任务并行库)中获益。
任务
线程之上的抽象。 它使用线程池 (除非您将任务指定为LongRunning
操作,否则将为您创建一个新线程)。
线程池
顾名思义:线程池。 .NET框架为您处理有限数量的线程。 为什么? 因为在一个只有8核心的处理器上打开100个线程来执行昂贵的CPU操作是不是一个好主意。 该框架将为您维护该池,重用线程(不在每个操作中创建/杀死它们),并且以并行方式执行其中一些线程,以便CPU不会烧毁。
好的,但什么时候使用每一个?
在简历中:总是使用任务。
任务是一个抽象,所以它使用起来更容易。 我建议你总是尝试使用任务,如果你遇到一些问题,使你需要自己处理一个线程(可能是1%的时间),然后使用线程。
但请注意:
- I / O绑定 :对于I / O绑定操作(数据库调用,读/写文件,API调用等),避免使用正常的任务,如果需要的话,使用
LongRunning
任务或线程。 因为使用任务会导致您有一些线程繁忙的线程池,还有很多其他任务正在等待轮到池。 - CPU绑定 :对于CPU绑定的操作,只需使用正常的任务(内部将使用线程池)并开心。
任务就像一个你想要执行的操作,线程有助于通过多个进程节点来管理这些操作。 任务是一个轻量级的选项,因为线程可以导致一个复杂的代码管理
我会建议阅读MSDN(世界上最好的)总是
任务
线
除了以上几点之外,最好还是要知道:
- 任务默认是后台任务。 你不能有一个前台任务。 另一方面,线程可以是后台或前台(使用IsBackground属性来改变行为)。
- 线程池中创建的任务回收线程,这有助于节省资源。 所以在大多数情况下,任务应该是你的默认选择。
- 如果操作很快,则使用任务而不是线程要好得多。 对于长时间运行的操作,任务不会比线程提供更多优势。