在C#中如何在同一个线程中运行方法异步

时间:2013-04-27 18:32:03

标签: c# multithreading asynchronous

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

修改 我问的原因是nodejs服务模型 - 一个线程上的所有东西都没有阻塞任何东西,这被证明是非常有效的,这让我想知道C#中是否有相同的东西(我自己也无法实现)。

Edit2 好吧,正如评论中所述,节点毕竟不是单线程的(不过简单的负载测试显示,它只使用一个核心...),但我认为是什么让它成为现实如此高效是隐式要求只写非阻塞代码。这在C#中是可能的,除了不需要:)无论如何,谢谢大家...

中的更多信息 this SO post以及this one

中的更多内容

1 个答案:

答案 0 :(得分:9)

目前还不清楚你正在谈论的是什么语境,但C#5的async / await功能已经有助于支持这类事情。不同之处在于,在node.js中,默认情况下强制一切都是单线程的(据我所知;很可能错误地给出了注释中的链接),.NET中的服务器端应用程序使用异步将使用非常少的线程而不限制自己。如果所有的一切都可以由单个线程提供,那么很可能 - 如果你在物理处理方面从来没有做过多件事,那就没关系了。

但是如果一个请求进入而另一个请求做了一些工作呢?也许它只是进行少量加密,或类似的东西。你真的想让第二个请求等待第一个请求完成吗?如果你这样做,你可以使用与单线程线程池关联的TaskScheduler相当容易地在.NET中建模...但更常见的是,你使用线程 - .NET内置的池,可以高效工作,同时仍允许并发。

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

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

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

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

按照上面的两个链接查找有关C#5中异步支持的更多信息 - 这是一个巨大的主题,我相信你之后会有更多的问题,但是当你有了阅读更多,您应该能够提出非常特定的问题,而不是当前广泛的问题。