编辑 - 阅读下面的三个答案后,我意识到我在胡说八道!抱歉浪费你宝贵的一些时间,并感谢你澄清了很多误解,真的! :)
我假设apples and pipe wrenches与async / await的方式相同,而线程也是类似问题的解决方案。 Async/await
和Threads
都解决了UI响应问题,但不是以相同的方式。前者是一种模式,可以在异步收集多个所需结果时使用(例如为了改善用户体验),因此它被称为“异步”。繁重的工作,需要几秒钟到几小时的工作必须在另一个线程上卸载以保持UI响应。这两者完全不同。
无论我如何编辑这个问题,都无法在有或没有线程问题的情况下询问async / await,因为它们是完全不同的东西,可以一起使用(在很多方面)或单独使用。下面的声明.2说明了一切(除了“调用”误解),但我从一开始就没有真正理解它的真正含义。
我想我应该从怀疑的那一刻起删除这个问题,但在实际阅读一些答案之前,我无法理解它是多么愚蠢。但是,这也可能有助于其他人更好地了解async / await是什么。
顺便说一句,我不知道答案是什么答案,因为他们都有有价值的信息。
原帖:
值得注意的是,我“又是另一个异步/等待初学者”。但是,到目前为止我所理解的是:
threads
!从不!它们与调用者在同一个线程上运行。Thread.Sleep
(应改为使用Task.Delay
)或Exception
Finally
阻止。{/ li>
醇>
基于以上所述,为了简化操作,我认为async / await只是 goto
的一种改进形式,能够从方法步骤跳转到另一个方法步骤,因为goto
呼叫可以“飞行”(被延迟),直到遇到等待! (对不起,简化目前的事情)
我已经测试了I / O和CPU代码而没有额外的线程,两者都很重,并且两者都产生了无响应 UI,直到所有内容都完成。
我的观察:
没有异步功能之类的东西:
.net
对象之一或其自己创建线程的成员明确定义的线程IO devices
async/await
只是简单的同步模式;意思是,只有async/await
个关键字在任何地方都没有类似异步的东西。
问题是:上述观察结果是真的,还是我遗漏了
async/await
的一些重要内容?
附注:
我读过这个blog post(没有线程,Stephen Cleary的博客)。他声明没有线程(完全同意),但它与我的观察结果并不矛盾,在没有涉及异步设备的纯程序员代码级别,除非您在另一个线程中委派繁重的任务,否则不能拥有响应式UI。我关心的不是模式的 awaitable 方面,正如我所说,它就像一个飞行的goto;我想确保我不是为了使用新的东西而盲目地使用async/await
。
.ConfigureAwait(false)
:似乎涉及一个ThreadPool,这就是为什么UI线程仍然响应......
答案 0 :(得分:3)
Async-await是一种模式,允许您编写与同步代码非常相似但实际上可以异步执行的代码。这依赖于编译器完成的大量工作。就是这样。
Async-await不会创建异步操作,它只允许您以简单的方式使用它们,并且仍然是异步的,与使用BeginXXX
/ EndXXX
之前不同。
确实,异步对I / O非常有用,因为大多数异步操作都是I / O操作,但有不同的操作,如Task.Delay
,异步同步机制或异步等待事件。
关于您的具体要点:
ThreadPool
线程或SynchronizationContext
或{{ 1}}。TaskScheduler
而失败。使用Thread.Sleep
来阻止线程是浪费的。这就是你使用Thread.Sleep
的原因。您现在可以使用C#6等待Task.Delay
。最后:
意思是,只有async / await关键字在任何地方都没有类似异步的东西。
是的,使用finally
关键字标记方法不会使任何异步运行。它只允许您使用async
并将结果包装在await
。
答案 1 :(得分:3)
您可能会发现我的async
intro有帮助。
我会说async
和await
是使用异步操作的最佳方式。作为副产品,async
还会创建更高级别的异步操作(如果方法返回Task
/ Task<T>
)。但是,它们不是从无到有创建异步操作的好方法。
所以我不同意这句话:
async / await只是简单的同步模式
但是,我同意await
只是将async
方法分解为多个同步部分的声明。
如果你有CPU绑定代码并且你不想阻止UI线程,那么你可以使用类似Task.Run
的东西将该代码推送到线程池线程。然后,UI代码可以await
从Task.Run
返回任务。
答案 2 :(得分:2)
这里有两个截然不同的概念。 异步和并行并不是一回事。虽然异步操作可以隐藏多线程,但他们不一定会这样做。
C#中的async
/ await
关键字只是表达诸如“当操作A完成时,执行操作B”之类的想法的语法糖。操作A是否在另一个线程上运行是一个您不关心的实现细节。
基本上,您让编译器和框架为您解决问题。
如果你想到它,async
/ await
在概念上可能与事件和事件循环的工作方式有些相似。也许event
语法不够灵活,这也是他们引入这些新关键字的原因。就我个人而言,我认为它与JavaScript中的promises相同,或者Node.js中的事件循环是如何工作的。我并不是说它的工作方式类似,但确实解决了类似的问题。