我来自后端/胖客户端背景,所以也许我错过了一些东西......但是我最近查看了一个开源JWT令牌服务器的来源,并且作者对await / async感到疯狂。就像每个方法和每一行一样。
我得到的模式是...在一个单独的线程中运行长时间运行的任务。在我厚厚的客户端,我会使用它,如果一个方法可能需要几秒钟,以便不阻止GUI线程...但绝对不是一个需要几毫秒的方法。
这是否过度使用了await / async你需要的web dev或类似Angular的东西?这是在JWT令牌服务器中,因此甚至没有看到它与任何这些服务器有什么关系。它只是一个REST终点。
如何让每一行异步都能提高性能?对我而言,它会扼杀所有这些线程的性能,不是吗?
答案 0 :(得分:3)
通常这是因为一旦异步函数与其他异步函数相比更好,否则你开始失去异步性的好处。因此,调用异步函数的函数最终会自动异步,并在整个应用程序中传播,例如。如果你与数据存储异步进行了交互,那么利用该功能的东西往往也会变成异步。
当您将同步代码转换为异步代码时,您会发现,如果异步代码调用并且被其他异步代码调用 - 它一直向下(或“向上”,如果您愿意),它最有效。其他人也注意到异步编程的传播行为,并将其称为“具有传染性”或将其与僵尸病毒进行比较。无论是海龟还是僵尸,异步代码往往会驱使周围的代码也是异步的。这种行为是所有类型的异步编程所固有的,而不仅仅是新的async / await关键字。
答案 1 :(得分:1)
这是一个演员模特世界,真的......
我认为async / await只是一种打扮软件系统的方式,以避免不得不承认,真的,很多系统(特别是那些拥有大量网络通信的系统)更好地被视为Actor模型(或者更好的是,通信顺序过程)系统。
对于这两者而言,重点在于你等待几件事中的一件变得完整,在一件事情中采取必要的行动,然后再回到等待状态。具体来说,您正在等待来自其他地方的消息,阅读消息以及对内容采取行动。在* nix中,等待通常通过调用epoll()或select()来完成。
使用await / async只是假装你的系统仍然是同步方法调用(因而熟悉)的一种方式,同时使得难以有效地处理每次都不按顺序完成相同顺序的事情。
然而,一旦你克服了你不再调用方法而只是简单地来回传递消息的想法,一切都变得非常自然。这是一个“请做这个”,“确定,这是答案”的事情,许多这样的互动交织在一起。在循环顶部用一个大的WaitForLotsOfThings()调用来包装它只是一个明确的确认,你的程序将等到它有任何事情要做以响应许多其他与之通信的程序。
Windows如何变得困难
不幸的是,Windows使得实现一个proactor系统变得非常困难(“如果你现在阅读那个消息,你就会得到它”)。 Windows是反应堆(“你要我读的那条消息?现在已经读过了。”)。这是一个重要的区别。
对于前者,一个消息(或者实际上是一个超时)意味着“停止听另一个演员”很容易处理 - 你只需从下次等待时你将听到的列表中排除其他演员。
使用反应堆,这要困难得多。当读取已经通过某种异步调用启动时,如何尊重“停止侦听其他actor”消息,并且在读取某些内容之前不会完成,根据最近收到的指令会产生可疑结果?
我在某种程度上挑剔。 Proactor在具有动态连接的系统中非常有用,Actors掉入系统,再次退出。如果你有一个固定的演员群体,并且通信链接永远不会消失,那么Reactor就可以了。尽管如此,鉴于反应器系统很容易在一个反应器平台中实施,但是一个反应器系统不能在反应堆平台上轻松实现(时间不会倒退),我发现Window的方法特别令人恼火。
所以无论如何,async / await肯定还在反应堆土地上。
敲击影响力
这已经感染了许多其他库。
C ++的Boost asio也是反应堆,即使在* nix上,很大程度上似乎是因为他们想要一个Windows实现。
ZeroMQ是一个proactor框架,在某种程度上限制在Windows基于对select()的调用(在Windows中仅适用于套接字)。
对于Windows上的cygwin系列POSIX运行时,他们必须通过每个文件描述符轮询的线程来实现select(),epoll()等(是的, 轮询 !!!!)传入数据的底层套接字/串行端口/管道,以便重新创建POSIX的例程。 Yeurk!关于cygwin开发者邮件列表的评论可以追溯到他们实施该部分的时间,这些都是有趣的阅读。
演员不一定慢“
值得注意的是,“传递消息”这个短语并不一定意味着传递副本 - 有很多演员模型的表达式,你只是将所有引用信息传递给周围的消息(例如Dataflow,任务的一部分) C#中的并行库。这使得它很快。我还没有看过Dataflow库,但它并没有真正让Windows proactor突然出现。它没有给你一个演员模型proactor系统工作在各种数据承载,如套接字,管道,队列等。
Windows 10的Linux运行时
因此,刚刚抨击Windows及其劣质反应器架构,一个有趣的观点是Windows 10现在运行Linux二进制文件。我非常想知道,微软是否实现了基于select(),epoll()的系统调用,因为它必须在套接字,串行端口,管道以及POSIX的所有其他地方运行。文件描述符,当Windows上的其他一切都不能?我会让我的后牙知道这个问题的答案。