C# 它';最好使用普通的旧线程对象,而不是一个较新的结构?

C# 它';最好使用普通的旧线程对象,而不是一个较新的结构?,c#,.net,multithreading,C#,.net,Multithreading,我在博客帖子中看到很多人,在最近的C#版本中,他们要么避免使用线程类,要么建议不要使用线程类(当然,我指的是4.0+,还添加了任务&朋友)。甚至在这之前,就有关于一个普通旧线程的功能在许多情况下可以被ThreadPool类替换的争论 另外,其他专门的机制进一步降低了线程类的吸引力,例如计时器替代了丑陋的线程+睡眠组合,而对于GUI,我们有后台工作人员等 尽管如此,Thread似乎仍然是一些人(包括我自己)非常熟悉的概念,他们在面对涉及某种并行执行的任务时,直接跳到使用好的旧Thread类。我最近

我在博客帖子中看到很多人,在最近的C#版本中,他们要么避免使用
线程
类,要么建议不要使用
线程
类(当然,我指的是4.0+,还添加了
任务
&朋友)。甚至在这之前,就有关于一个普通旧线程的功能在许多情况下可以被
ThreadPool
类替换的争论

另外,其他专门的机制进一步降低了
线程
类的吸引力,例如
计时器
替代了丑陋的
线程
+
睡眠
组合,而对于GUI,我们有
后台工作人员

尽管如此,
Thread
似乎仍然是一些人(包括我自己)非常熟悉的概念,他们在面对涉及某种并行执行的任务时,直接跳到使用好的旧
Thread
类。我最近一直在想,是不是该改过自新了


因此,我的问题是,在任何情况下,使用普通的
线程
对象而不是上述构造之一都是必要的或有用的吗?

线程是某些事物(即并行性和异步性)的基本构造块,因此不应该被删除。但是,对于大多数人和大多数用例来说,您提到的还有一些更合适的东西可以使用,比如线程池(它提供了一种很好的方法,可以并行处理许多小作业,而不会通过一次生成2000个线程而使机器过载),
BackgroundWorker
(它封装了单个短期工作的有用事件)

但是,仅仅因为在许多情况下,这些更合适,因为它们保护程序员避免不必要地重新发明轮子、犯愚蠢的错误等等,这并不意味着Thread类已经过时。它仍然被上面提到的抽象所使用,如果您需要对线程进行细粒度的控制,那么您仍然需要它它不在更特殊的课程范围内


类似地,
.NET
也不禁止使用数组,尽管
List
更适合于人们使用数组的许多情况。这仅仅是因为您可能仍然希望构建标准库中未包含的内容。

您可以将Thread类与ADO.NET进行比较。它不是获取这项工作已经完成,但还没有过时。其他工具也在此基础上构建,以简化这项工作


在其他事物上使用Thread类并没有错,特别是当这些事物没有提供您所需要的功能时。

任务
线程
是不同的抽象。如果您想对线程建模,
线程
类仍然是最合适的选择。例如,如果您需要与curr进行交互耳鼻喉科线程,我没有看到任何更好的类型为这个

但是,正如您所指出的,在许多情况下,.NET添加了几个专用的抽象,比
线程更可取。

新的选项减少了直接使用和管理(昂贵)线程的频率

当遇到涉及某种并行执行的任务时,直接跳到使用好的旧线程类的人

这是一种非常昂贵且相对复杂的并行处理方式


请注意,费用是最重要的:你不能用一个完整的线程来完成一项小的工作,这会适得其反。线程池可以解决成本、任务类和复杂性(异常、等待和取消).

线程类不能过时,因为它显然是您提到的所有其他模式的实现细节

但这不是你真正的问题,你的问题是

在任何情况下,使用普通的旧线程对象而不是上述构造之一都是必要或有用的吗

当然可以。在某些情况下,其中一个更高层次的结构不能满足您的需要


我的建议是,如果您发现现有的高级抽象工具不能满足您的需求,并且您希望使用线程实现解决方案,那么您应该确定您真正需要的缺少的抽象,然后使用线程实现该抽象,然后使用该抽象。

这不是确定的过时了

多线程应用程序的问题在于它们很难正确运行(通常不确定的行为、输入、输出以及内部状态都很重要),因此程序员应该尽可能多地将工作推到框架/工具上。将其抽象掉。但是,抽象的致命敌人是性能

所以我的问题是,有没有必要或有用的案例 使用普通的旧线程对象而不是上述对象之一 构造


只有在出现严重的性能问题和高性能目标时,我才会使用线程和锁。

线程类并没有过时,它在特殊情况下仍然很有用

在我工作的地方,我们编写了一个“后台处理器”,作为内容管理系统的一部分:一个Windows服务,它监视目录、电子邮件地址和RSS源,每次出现新的内容时,都在上面执行一项任务,通常是导入数据

尝试使用线程池对此不起作用:它试图在同一时间执行太多的内容并将磁盘丢弃,因此我们直接使用
线程
类实现了我们自己的轮询和执行系统。

回答了“在任何情况下使用普通的旧线程对象是必要的还是有用的”的问题,我想说一个普通的旧线程是有用的(但不是必需的),当你有一个长时间运行的进程,你永远不会从一个不同的线程进行交互

例如,如果您正在编写一个