我在 C#/.Net 中做了很多开发,异步故事从第一天起就一直存在(诚然,多年来 API 从开始/结束到事件发生了显着变化,到 Task<T>
和 async
/await
).在过去一年左右的时间里,我一直在使用 Node.js 进行开发,它异步执行所有 I/O 并使用单线程事件循环模型。最近我在做一个我们使用 Ruby 的项目,对于应用程序的一部分,我觉得异步地发出一大堆 Web 请求是有意义的,并且惊讶地发现 Ruby 中的异步故事是巨大的不同的。执行任何异步 I/O 的唯一方法是使用 EventMachine
。
我的问题归结为:为什么在 .Net 中(据我所知,Java/JVM 也是如此)不需要事件循环,而且我可以触发异步请求在任何时候,但在像 Ruby/Python 这样的语言中,我需要分别求助于 eventmachine/twisted 吗?我觉得我不了解有关异步 I/O 工作原理的一些基本知识。
最佳答案
My question comes down to this: Why is it that in .Net (and from what I can tell this is true for Java/JVM as well) there's no need for an event loop, and I can fire off an asynchronous request at any time, yet in languages like Ruby/Python, I need to resort to eventmachine/twisted respectively?
我认为这是因为 Ruby/Python(以及无缝的 Node.js)希望通过为应用程序的核心循环强加单线程模型来让开发人员的生活更轻松。使用事件机,异步 I/O 例程的完成回调被序列化并排队以在同一线程上执行,因此开发人员不必担心线程安全。
我不能代表 Java,但在 .NET 中,我们可以通过同步上下文 控制它。查看 Stephen Cleary 的 "It's All About the SynchronizationContext" .在 .NET 中复制事件机的概念非常容易(实际上,这是为 UI 应用程序自动完成的)。序列化同步上下文的自定义实现可能类似于 Stephen Toub 的 "Await, SynchronizationContext, and Console Apps" 中的 AsyncPump
. IMO,这将直接匹配 Ruby 的事件机器。
关于.net - 为什么异步 I/O 需要事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24197255/