3

是否可以在与调用者相同的线程中异步定义和调用方法?假设我只有一个内核,并且我不希望有 100 个线程的线程管理开销。

编辑 我问的原因是nodejs的做事模型——一个线程上的所有东西都不会阻塞任何东西,这被证明是非常有效的,这让我想知道在C#中是否可以实现相同的东西(我自己无法实现)。

Edit2好吧,正如评论中指出的那样,节点毕竟不是单线程的(但是简单的负载测试表明,它只使用一个核心......),但我认为它如此高效的原因是隐含要求只编写非阻塞代码。这在 C# 中是可能的,除了不需要:) 无论如何,谢谢大家......

此 SO 帖子中的更多信息,甚至更多信息

4

1 回答 1

9

目前还不清楚你在说什么上下文,但是 C# 5 的async/await特性已经有助于支持这种事情。不同之处在于,虽然在 node.js 中,默认情况下所有内容都强制为单线程(据我了解;很可能不正确地给出了评论中的链接),而在 .NET 中使用异步的服务器端应用程序将使用很少的线程而不使用限制自己。如果真的所有事情都可以由单个线程提供服务,那很可能 - 如果您在物理处理方面要做的事情不止一件事,那很好。

但是,如果一个请求进来而另一个请求正在做一些工作怎么办?也许它只是做少量的加密,或者类似的东西。您真的要让第二个请求等待第一个请求完成吗?如果你这样做了,你可以很容易地在 .NETTaskScheduler中使用与单线程线程池相关联的模型来建模......但更常见的是,你会使用 .NET 中内置的线程池,它可以在仍然有效的情况下工作允许并发。

首先,您应该确保您使用的是 .NET 4.5 - 它比早期版本的 .NET 具有更多的异步 API(例如,用于数据库和文件访问)。您想使用符合基于任务的异步模式 (TAP)的 API 。然后,使用async/await您可以编写服务器端代码,使其读起来有点像同步代码,但实际上是异步执行的。例如,您可能有:

Guid userId = await FetchUserIdAsync();
IEnumerable<Message> messages = await FetchMessagesAsync(userId);

即使您需要在每个操作进行时“等待”,您也可以在不阻塞线程的情况下这样做。C# 编译器负责为您构建状态机。无需显式编写经常变成意大利面条代码的回调 - 编译器会完成所有工作。

您需要确保您使用的任何 Web/Web 服务框架都支持异步,并且它应该只管理其余的,使用尽可能少的线程。

按照上面的两个链接了解更多关于 C# 5 中的异步支持的信息——这是一个很大的话题,我相信你之后会有更多的问题,但是当你阅读更多内容时,你应该能够问非常具体的问题,而不是当前广泛的问题。

于 2013-04-27T19:22:10.807 回答