首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TPL和async/await (线程处理)之间的区别

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

Stack Overflow用户
提问于 2012-04-24 01:20:38
回答 2查看 27.9K关注 0票数 73

当涉及到线程创建时,尝试理解第三方编程语言和async/await之间的区别。

我认为第三方公共许可证(TaskFactory.StartNew)的工作原理类似于ThreadPool.QueueUserWorkItem,因为它将线程池中的线程上的工作排入队列。当然,除非您使用创建新线程的TaskCreationOptions.LongRunning

我认为async/await的工作原理类似,所以本质上是这样的:

第三方物流:

代码语言:javascript
复制
Factory.StartNew( () => DoSomeAsyncWork() )
.ContinueWith( 
    (antecedent) => {
        DoSomeWorkAfter(); 
    },TaskScheduler.FromCurrentSynchronizationContext());

Async/Await

代码语言:javascript
复制
await DoSomeAsyncWork();  
DoSomeWorkAfter();

都是一样的。根据我所读到的,似乎async/await只是“有时”创建了一个新线程。那么它什么时候创建新线程,什么时候不创建新线程呢?如果您正在处理IO完成端口,我可以看到它不必创建新线程,但我认为它必须创建新线程。我想我对FromCurrentSynchronizationContext的理解也总是有些模糊。我一直认为它本质上就是UI线程。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-24 02:56:52

我认为第三方公共关系(TaskFactory.Startnew)的工作原理类似于ThreadPool.QueueUserWorkItem,因为它将线程池中的线程上的工作排队。

Pretty much

从我所读到的

看起来异步/等待只是“有时”创建一个新线程。

实际上,它从来都不会。如果你想要多线程,你必须自己实现它。有一种新的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类型的--它不一定是async方法。因此,Task.Delay和I/O绑定操作只是使用TaskCompletionSource来创建和完成任务-线程池上唯一要做的事情就是在事件发生时实际完成任务(超时、I/O完成等)。

我猜我对FromCurrentSynchronizationContext的理解也总是有点模糊。我一直认为它本质上就是UI线程。

我在SynchronizationContext上写了an article。大多数情况下,SynchronizationContext.Current

如果当前线程是UI线程,则

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

任何线程都可以设置自己的SynchronizationContext,所以上面的规则有例外。

请注意,如果async方法的其余部分不为空,则默认的Task等待程序将在当前SynchronizationContext上调度该方法的其余部分;否则,它将在当前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主机中,您实际上可以得到“零线程并发”。真是太贴心了。

票数 86
EN

Stack Overflow用户

发布于 2012-04-24 01:27:39

async / await基本上简化了ContinueWith方法( Continuation Passing Style中的延续)

它没有引入并发性--你仍然需要自己去做(或者使用框架方法的异步版本。)

因此,C# 5版本为:

代码语言:javascript
复制
await Task.Run( () => DoSomeAsyncWork() );
DoSomeWorkAfter();
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10285159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档