gpt4 book ai didi

multithreading - TPL 和 async/await 之间的区别(线程处理)

转载 作者:行者123 更新时间:2023-12-03 05:39:32 25 4
gpt4 key购买 nike

尝试了解 TPL 和 async/await 在线程创建方面的区别。

我相信 TPL (TaskFactory.StartNew) 的工作方式与 ThreadPool.QueueUserWorkItem 类似,因为它对线程池中的线程上的工作进行排队。当然,除非您使用创建新线程的 TaskCreationOptions.LongRunning

我认为async/await本质上会以类似的方式工作:

TPL:

Factory.StartNew( () => DoSomeAsyncWork() )
.ContinueWith(
(antecedent) => {
DoSomeWorkAfter();
},TaskScheduler.FromCurrentSynchronizationContext());

异步/等待:

await DoSomeAsyncWork();  
DoSomeWorkAfter();

将是相同的。从我读到的内容看来,async/await仅“有时”创建一个新线程。那么什么时候创建新线程,什么时候不创建新线程呢?如果您正在处理 IO 完成端口,我可以看到它不必创建新线程,但否则我认为它必须创建。我想我对 FromCurrentSynchronizationContext 的理解也总是有点模糊。我一直认为它本质上是 UI 线程。

最佳答案

I believe the TPL (TaskFactory.Startnew) works similar to ThreadPool.QueueUserWorkItem in that it queues up work on a thread in the thread pool.

Pretty much .

From what i've been reading it seems like async/await only "sometimes" creates a new thread.

事实上,从来没有。如果想要多线程,就得自己实现。有一个新的 Task.Run 方法,它只是 Task.Factory.StartNew 的简写,它可能是在线程池上启动任务的最常见方法。

If you were dealing with IO completion ports i can see it not having to create a new thread but otherwise i would think it would have to.

宾果游戏。因此,像 Stream.ReadAsync 这样的方法实际上会围绕 IOCP 创建一个 Task 包装器(如果 Stream 有 IOCP)。

您还可以创建一些非 I/O、非 CPU“任务”。一个简单的例子是 Task.Delay,它返回一个在一段时间后完成的任务。

关于async/await的一个很酷的事情是,您可以将一些工作排​​队到线程池中(例如,Task.Run),执行一些 I/O 绑定(bind)操作(例如,Stream.ReadAsync),并执行一些其他操作(例如,Task.Delay)...任务!它们可以等待或组合使用,例如 Task.WhenAll

任何返回 Task 的方法都可以进行 await 处理 - 它不必是 async 方法。因此,Task.Delay 和 I/O 绑定(bind)操作只需使用 TaskCompletionSource 来创建和完成任务 - 线程池上执行的唯一操作是实际任务完成时事件发生(超时、I/O 完成等)。

I guess my understanding of FromCurrentSynchronizationContext always was a bit fuzzy also. I always throught it was, in essence, the UI thread.

我写了an articleSynchronizationContext 上。大多数时候,SynchronizationContext.Current:

  • 如果当前线程是 UI 线程,则为 UI 上下文。
  • 如果当前线程正在处理 ASP.NET 请求,则为 ASP.NET 请求上下文。
  • 否则是线程池上下文。

任何线程都可以设置自己的SynchronizationContext,因此上述规则也有异常(exception)。

请注意,默认的 Task 等待程序将在当前 SynchronizationContext 上调度 async 方法的剩余部分(如果它不为 null) ;否则它将继续执行当前的TaskScheduler。这在今天并不那么重要,但在不久的将来它将成为一个重要的区别。

我自己写的async/await intro在我的博客上,Stephen Toub 最近发布了一篇出色的文章 async/await FAQ .

关于“并发”与“多线程”,请参阅this related SO question 。我想说,async 支持并发,它可能是多线程的,也可能不是。使用 await Task.WhenAllawait Task.WhenAny 进行并发处理很容易,除非您显式使用线程池(例如 Task.RunConfigureAwait(false)),那么您可以同时进行多个并发操作(例如,多个 I/O 或其他类型,如 Delay) - 他们不需要线程。对于这种情况,我使用术语“单线程并发”,但在 ASP.NET 主机中,您实际上可能会得到“线程并发”。这很甜蜜。

关于multithreading - TPL 和 async/await 之间的区别(线程处理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10285159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com