关键词:
【中文标题】TPL 和 async/await 之间的区别(线程处理)【英文标题】:Difference between the TPL & async/await (Thread handling) 【发布时间】:2012-05-04 08:05:19 【问题描述】:在线程创建方面尝试了解 TPL 和 async
/await
之间的区别。
我相信 TPL (TaskFactory.StartNew
) 的工作方式类似于 ThreadPool.QueueUserWorkItem
,因为它在线程池中的线程上排队工作。当然,除非您使用 TaskCreationOptions.LongRunning
创建一个新线程。
我认为async
/await
的工作原理与此类似:
TPL:
Factory.StartNew( () => DoSomeAsyncWork() )
.ContinueWith(
(antecedent) =>
DoSomeWorkAfter();
,TaskScheduler.FromCurrentSynchronizationContext());
Async
/Await
:
await DoSomeAsyncWork();
DoSomeWorkAfter();
将是相同的。从我一直在阅读的内容来看,async
/await
似乎只有“有时”会创建一个新线程。那么它什么时候创建一个新线程,什么时候不创建一个新线程呢?如果您正在处理 IO 完成端口,我可以看到它不必创建新线程,否则我认为它必须这样做。我想我对FromCurrentSynchronizationContext
的理解也总是有点模糊。我一直认为它本质上是 UI 线程。
【问题讨论】:
实际上,TaskCreationOptions.LongRunning 并不能保证“新线程”。根据 MSDN,“LongRunning”选项仅向调度程序提供提示;它不保证有一个专用线程。我发现了这个困难的方式。 @eduncan911 尽管您对文档的看法是正确的,但我不久前查阅了 TPL 源代码,我很确定实际上在TaskCreationOptions.LongRunning
时总是会创建一个新的专用线程已指定。
@ZaidMasud:你可能想再看看。我知道它正在合并线程,因为 Thread.CurrentThread.IsThreadPoolThread
对于几百毫秒的短时间运行线程返回 true。更不用说我使用的 ThreadStatic 变量渗入多个线程,导致各种破坏。我不得不强制我的代码新建多个 Thread(),这是老式的方式,以保证专用线程。换句话说,我不能将 TaskFactory 用于专用线程。或者,您可以实现自己的 TaskScheduler
,它始终返回一个专用线程。
【参考方案1】:
我相信 TPL (TaskFactory.Startnew) 的工作方式与 ThreadPool.QueueUserWorkItem 类似,因为它将线程池中线程上的工作排队。
Pretty much.
从我一直在阅读的内容来看,async/await 似乎只是“有时”会创建一个新线程。
实际上,它从来没有。如果你想要多线程,你必须自己实现它。有一个新的Task.Run
方法,它只是Task.Factory.StartNew
的简写,它可能是在线程池上启动任务的最常用方法。
如果您正在处理 IO 完成端口,我可以看到它不必创建新线程,否则我认为它必须这样做。
宾果游戏。所以像 Stream.ReadAsync
这样的方法实际上会在 IOCP 周围创建一个 Task
包装器(如果 Stream
有一个 IOCP)。
您还可以创建一些非 I/O、非 CPU 的“任务”。一个简单的例子是Task.Delay
,它返回一个在一段时间后完成的任务。
async
/await
很酷的一点是,您可以将一些工作排队到线程池(例如,Task.Run
),执行一些 I/O 绑定操作(例如,Stream.ReadAsync
),以及做一些其他操作(例如,Task.Delay
)......它们都是任务!它们可以被等待或组合使用,例如Task.WhenAll
。
任何返回Task
的方法都可以是await
ed - 它不必是async
方法。所以Task.Delay
和 I/O 绑定操作只需使用TaskCompletionSource
来创建和完成任务——线程池上唯一要做的就是事件发生时的实际任务完成(超时、I/O 完成等) )。
我想我对 FromCurrentSynchronizationContext 的理解也总是有点模糊。我一直认为它本质上是 UI 线程。
我在SynchronizationContext
上写了an article。大多数时候,SynchronizationContext.Current
:
任何线程都可以设置自己的SynchronizationContext
,所以上面的规则也有例外。
注意默认的Task
awaiter 会在当前SynchronizationContext
上调度async
方法的剩余部分如果它不为空;否则它将继续当前的TaskScheduler
。这在今天并不那么重要,但在不久的将来它将是一个重要的区别。
我在博客上写了自己的async
/await
intro,Stephen Toub 最近发布了一个出色的async
/await
FAQ。
关于“并发”与“多线程”,请参阅this related SO question。我想说async
启用并发,这可能是也可能不是多线程的。使用await Task.WhenAll
或await Task.WhenAny
做并发处理很容易,除非你显式使用线程池(例如Task.Run
或ConfigureAwait(false)
),那么你可以同时进行多个并发操作(例如,多个 I/O 或其他类型,如 Delay
) - 它们不需要线程。对于这种情况,我使用术语“单线程并发”,尽管在 ASP.NET 主机中,您实际上可以得到“零-线程并发”。这很甜蜜。
【讨论】:
不错的答案。我还推荐infoq.com/articles/Async-API-Design 和这个出色的演示:channel9.msdn.com/Events/TechEd/Europe/2013/DEV-B318。 第一个链接失效了。 “async/await FAQ”链接失效 是的。微软移动了一堆东西,并破坏了几乎所有指向其内容的链接。此答案接受 PR。【参考方案2】:async / await 基本上简化了ContinueWith
方法(在Continuation Passing Style 中继续)
它没有引入并发——你仍然需要自己做(或者使用框架方法的异步版本。)
因此,C# 5 版本将是:
await Task.Run( () => DoSomeAsyncWork() );
DoSomeWorkAfter();
【讨论】:
那么在我上面的示例中,它在哪里运行 DoSomeAsyncWork(异步/等待版本)?如果它在 UI 线程上运行,它如何不阻塞? 如果DoSomeWorkAsync()
返回 void 或不可等待的东西,您的 await 示例将无法编译。从您的第一个示例中,我假设它是您希望在不同线程上运行的顺序方法。如果您将其更改为返回Task
,而不引入并发,那么是的,它会阻塞。从某种意义上说,它会按顺序执行,就像 UI 线程上的普通代码一样。 await
仅在方法返回尚未完成的等待时才会产生。
好吧,我不会说它会在它选择运行的任何地方运行。您已使用 Task.Run 执行 DoSomeAsyncWork 中的代码,因此在这种情况下,您的工作将在线程池线程上完成。
我喜欢你的简洁回答。async/await和promise区别
async/await的优势:可以很好地处理then链对于单一的Promise链其实并不能发现async/await的优势,当需要处理由多个Promise组成的then链的时候,优势就能体现出来了,接下来直接上代码:/***传入参数n,表示这个函数执行的时间(毫秒... 查看详情
async(await)函数和generator函数区别
async函数是Generator函数的语法糖。async函数对Generator函数的改进体现在:1.async内置执行器。Generator函数的执行必须靠执行器,需要调用next()方法,或者用co模块;而async函数自带执行器。也就是说,async函数的执行与普通函数一模一... 查看详情
promise与async和await的区别(代码片段)
...og(awaitgetJSON)return"done"makeRequest()复制代码复制代码区别: 1)函数前面多了一个aync关键字。await关键字只能用在a 查看详情
Async/Await 和 Dispatcher 的区别
】Async/Await和Dispatcher的区别【英文标题】:DifferencebetweenAsync/AwaitandDispatcher【发布时间】:2021-09-2019:57:08【问题描述】:我正在开发一个WPF应用程序,我遇到了冻结问题,现在我知道它是一个单线程应用程序,但我对术语感到困... 查看详情
Callback 函数与 Promise 和 Async await 的区别
】Callback函数与Promise和Asyncawait的区别【英文标题】:differencebetweenCallbackfunctionandPromiseandAsyncawit【发布时间】:2019-09-2520:41:36【问题描述】:我了解回调函数,但我不了解promise方法和async和await。为什么在节点js中使用这三个函数... 查看详情
Task.Start/Wait 和 Async/Await 有啥区别?
】Task.Start/Wait和Async/Await有啥区别?【英文标题】:What\'sthedifferencebetweenTask.Start/WaitandAsync/Await?Task.Start/Wait和Async/Await有什么区别?【发布时间】:2012-03-2003:16:59【问题描述】:我可能遗漏了一些东西,但做这件事有什么区别:pu... 查看详情
promise和async的区别(代码片段)
promisePromise,我们了解到promise是ES6为解决异步回调而生,避免出现这种回调地狱,那么为何又需要Async/Await呢?你是不是和我一样对Async/Await感兴趣以及想知道如何使用,下面一起来看看这篇文章:Async/Await替代Promise的6个理由。... 查看详情
使用 async/await 会创建一个新线程吗?
】使用async/await会创建一个新线程吗?【英文标题】:Doestheuseofasync/awaitcreateanewthread?【发布时间】:2015-01-3116:01:20【问题描述】:我是TPL的新手,我想知道:C#5.0新增的异步编程支持(通过新的async和await关键字)与线程的创建有... 查看详情
nestjs 有或没有 async/await 有区别吗?
...【发布时间】:2020-12-2723:17:04【问题描述】:我认为以下之间没有区别:@Post()saveClient(@Param()params,@Body()createClientDto:ClientDto)this.clientRepository.save( 查看详情
async和await(代码片段)
...上async,该函数就变成了异步函数。该函数和普通函数的区别:异步函数的返回值是一个Promsie对象,相当于返回的值包裹在了Promise.resolve()内进行返回的异步函数内可以使用await关键字async函数内抛出错误,是通过返回值的Promsie... 查看详情
async await task.run xamarin 表单
...描述】:我只是想确保我理解asyncawait和Task.run或Task.whenall之间的区别所以asyncawait就是处理异步方法。这意味着有一个隐含的处理顺序。我在没有阻塞主线程的情况下运行了很长时间,并等待结果继续。对于Task.Run和T 查看详情
async与promise的区别(代码片段)
https://www.jianshu.com/p/51f5fd21588easync/await是基于promise实现的,他不能用于普通的回调函数async/await使得异步代码看起来像同步代码async/await与Promise一样,是非阻塞的。不同函数前面多了一个async关键字。await关键字只能用在async定义... 查看详情
在 Javascript 中的 API 调用之间使用 ASYNC/AWAIT 中的数组方法
】在Javascript中的API调用之间使用ASYNC/AWAIT中的数组方法【英文标题】:UsingArrayMethodinsideASYNC/AWAITbetweenAPIcallsinJavascript【发布时间】:2018-11-2102:56:30【问题描述】:我想让我的代码更具可读性,使用async/await而不是fetch()。我的代码... 查看详情
async,await与task.wait()或task.result的区别(代码片段)
...wait()或者task.Result的区别?接下来,一个Demo让你看出他们之间的区别。staticvoidMain(string[]args)Console.WriteLine("start");Test();//不等待Console.WriteLine("end");Console.Read();staticTask<int>Sleep()Console.WriteLine("Sleepstart");Thread.Sleep(1000);Console.WriteLi... 查看详情
async和await(代码片段)
async和awaitasync的使用await的使用在async和await出来之前,异步回调的方法就有1、回调嵌套2、Promsie的链式回调3、Generator的复杂繁琐调用方式async/await采用同步的思维来解决异步问题的方式,使代码的可读性更强了。async的使... 查看详情
async和await总结
...想要promise,想要promise异步执行的成功的value数据3.哪里写async?await所在函数(最近的)定义的左侧写async 查看详情
async和await(代码片段)
async和awaitAsync/await在NodeJS7.6引入,当前已被所有现代浏览器支持。简介async/await是一种新的使用异步代码的方式,代替之前回调或者promise的方式。是基于promise的语法糖,无法在普通的回调函数中使用,await必须在async方法中调用... 查看详情
async和await
...使用的Thread来使用异步多线程操作,基本上看不见有使用Async、Await进行异步编程的。各有所爱吧,其实都可以。只要正确使用就行,不过还是写了这篇文章推荐大家使用Async、Await。原因就是:可以跟写同步方法一样去异步编程... 查看详情