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

在C#中,如何在同一线程中运行异步方法,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,是否可以在调用方所在的同一线程中异步定义和调用方法? 假设我只有一个内核,我不希望线程管理开销达到100个线程 编辑 我问这个问题的原因是nodejs做事的模型——一个线程上的所有东西都不会阻塞任何东西,这被证明是非常有效的,这让我想知道同样的东西在C#中是否可能(我自己也做不到) Edit2正如注释中所指出的,节点毕竟不是单线程的(无论多么简单的负载测试表明,它只使用一个核心…),但我认为它之所以如此高效,是因为它隐含了只编写非阻塞代码的要求。这在C#中是可能的,除非不是必需的:)无论如何,谢

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

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

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

有关详细信息,请访问
甚至在

中,还不清楚您所说的是什么上下文,但是C#5的
异步
/
等待
特性已经有助于支持这类事情。不同之处在于,在node.js中,默认情况下所有内容都必须是单线程的(据我所知,注释中的链接很可能是错误的),而在.NET中使用异步的服务器端应用程序将使用很少的线程,而不会将其自身限制为单线程。如果每件事都可以由一个线程来完成,那么很可能是这样的——如果在物理处理方面,你从来没有不止一件事要做,那就好了

但是如果一个请求进来,而另一个正在做一点工作呢?也许它只是做了少量的加密,或者类似的事情。是否确实要让第二个请求等待第一个请求完成?如果您这样做了,您可以使用与单线程线程池关联的
TaskScheduler
在.NET中相当轻松地对其建模。。。但更常见的情况是,您会使用.NET内置的线程池,它可以高效地工作,同时仍然允许并发

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

Guid userId = await FetchUserIdAsync();
IEnumerable<Message> messages = await FetchMessagesAsync(userId);
Guid userId=await FetchUserIdAsync();
IEnumerable messages=wait FetchMessagesAsync(userId);
即使您需要在每个操作进行时“等待”,但这样做不会阻塞线程。C#编译器负责为您构建一个状态机。不需要显式地编写经常变成意大利面条代码的回调—编译器可以完成所有工作

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


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

@MattBall:假设异步操作不受CPU限制。假设异步操作是等待30秒,然后重置按钮的颜色。为什么要再增加一条线索呢?@ren:那就是说,马特·鲍尔有道理。所讨论的操作是否需要在另一个线程上运行取决于该操作的实现者。如果您想限制创建的线程数量,线程池就是为了这个。如果生成异步任务,TPL将负责从池中调度适当数量的线程,以使内核饱和。与其让我们继续猜测你在做什么,不如问一个关于实际问题的问题,而不是提出一个解决方案。如果你的问题是“我可以写一个程序,其中每个操作都是异步的,并且每个操作都在同一线程上吗?”那么答案是肯定的,当然你可以这样做。如果您是编写异步操作的人,那么您可以决定它运行的线程。如果您的问题是“我有一个使用线程池线程的ComputeFractalAsync方法,我希望它在当前线程上运行”,那么请致电编写该方法的人员,让他们为您编写一个不使用线程池的版本。nodejs不完全是单线程的。js实际上是同步到事件函数中的,所以您看不到多线程。如果你希望所有的调用都在同一个线程上,并且你正在编写所有的代码,那么永远不要创建一个新的线程。就这么简单。对于多线程,我真的很喜欢推荐Joseph Albahari的@metadings:这当然是一个很好的教程——但在异步世界中,它的很多内容在很大程度上是不相关的,因为在异步世界中,大多数时候不需要显式地启动新线程甚至新任务。异步和并发当然是相关的,但不是一回事。