在C#中的Tasks中使用线程是否毫无意义?

我知道differences between a thread and a task.,但是我无法理解在任务内部创建线程是否与仅创建线程相同。

cxjshxs 回答:在C#中的Tasks中使用线程是否毫无意义?

这取决于您如何使用多线程功能以及该语言的异步编程语义。

首先是简单事实。假设您有一个初始的,简单的,单线程的且几乎为空的应用程序(为简单起见,它仅读取Console.ReadLine的输入行)。如果您创建新的Thread,则您是从另一个线程 main 线程中创建的。因此,从一个线程中创建一个线程是一个完全有效的操作,也是任何多线程应用程序的起点。

现在,Task本身不是线程 ,但是当您从.NET托管线程池中选择Task.Run时,它会在一个线程中执行。这样,如果您从一个任务中创建一个新线程,则实际上是从一个线程中创建一个线程(与上面相同,没有造成任何伤害)。需要注意的是,您无法控制线程或其生命周期,也就是说,您无法杀死它,暂停它,恢复它,等等,因为您没有该线程的句柄。如果您希望某个工作单元完成,而又不在乎是哪个线程执行,只是不是当前线程,那么Task.Run基本上就是您可以采用的方法。话虽如此,您始终可以从任务中启动新线程,实际上,甚至可以从任务中启动任务,这是unwrapping nested tasks上的一些官方文档。 / p>

此外,您可以在任务内await,并根据需要在async方法内创建新线程。但是,asyncawait的可用性模式是将它们用于I / O绑定操作,这些操作需要很少的CPU时间,但是会花费很长时间,因为它们需要 wait ,例如网络请求和磁盘访问。对于响应式UI实施,该技术通常用于防止其他操作阻塞UI。

关于是否毫无意义,这是一个用例场景。我曾经遇到过可能是解决方案的情况,但是发现重新设计了程序逻辑,以便如果我需要在一个任务中使用线程,那么我要做的就是拥有两个任务: 而不是一个任务加上一个内螺纹,这给了我一种更整洁,更易读的代码结构,但这只是个人才能。

最后一点,这里是一些官方文档的链接,以及另一篇有关C#中多线程编程的文章:

,

这取决于您如何使用任务以及您想要另一个线程的原因。

任务。运行

如果使用Task.Run,则工作将“在ThreadPool上运行”。它将在与调用它的线程不同的线程上完成。这在桌面应用程序中很有用,在该应用程序中,您需要长时间运行处理器密集型操作,而该操作只需要退出UI线程即可。

区别在于您没有该线程的句柄,因此您无法以任何方式(暂停,恢复,终止,重用等)控制该线程。本质上,只要不关心工作发生在哪个线程上,只要它不是当前线程,就使用Task.Run

因此,如果您使用Task.Run启动任务,那么如果您知道自己为什么要这么做,就不会阻止您在其中启动新线程。如果您特别想出于特定目的重用线程句柄,则可以在任务之间传递线程句柄。

异步方法

使用asyncawait的方法用于处理时间很少但具有I / O操作的操作,这些操作需要等待。例如,网络请求,读取/写入本地存储等。使用asyncawait意味着线程在等待响应时可以自由做其他事情。好处取决于应用程序的类型:

  • 台式机应用:在等待响应时,UI线程可以自由响应用户输入。我确定您已经看到一些程序在等待某些响应时完全冻结。这就是异步编程可以帮助您避免的事情。

  • 网络应用:当前线程将被释放以执行所需的任何其他工作。这可以包括处理其他传入请求。结果是,与不使用asyncawait的应用程序相比,您的应用程序可以处理的负载更大。

也没有什么可以阻止您在async方法内启动线程。您可能需要将一些处理器密集型工作移到另一个线程。但是在那种情况下,您也可以使用Task.Run。因此,这完全取决于您为什么想要另一个线程。

,

在大多数日常编程情况下,这毫无意义。

在某些情况下,您将创建线程。

本文链接:https://www.f2er.com/3169811.html

大家都在问