C# 为什么要使用APM而不是使用单独的线程?

C# 为什么要使用APM而不是使用单独的线程?,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,如果我想读或写一个文件,我可以使用stream.BeginRead和stream.EndRead,但这需要回调和大量使用异步编程模型的难看、复杂的代码 为什么我要使用这些异步IO方法(在后台使用.NET线程池),而不是以同步方式编写相同的代码,并将其传递给线程池。(而不是用回调来破坏我的方法。) 更新: 一些(好的)响应表明,使用APM可以避免我创建线程——我同意这一点,因为每个新线程都有自己的2MB堆栈。但是“开始”和“结束”在哪里执行呢?线程池?重用已经分配的线程是唯一的好处吗?首先,您还应

如果我想读或写一个文件,我可以使用stream.BeginRead和stream.EndRead,但这需要回调和大量使用异步编程模型的难看、复杂的代码

为什么我要使用这些异步IO方法(在后台使用.NET线程池),而不是以同步方式编写相同的代码,并将其传递给线程池。(而不是用回调来破坏我的方法。)

更新:


一些(好的)响应表明,使用APM可以避免我创建线程——我同意这一点,因为每个新线程都有自己的2MB堆栈。但是“开始”和“结束”在哪里执行呢?线程池?重用已经分配的线程是唯一的好处吗?

首先,您还应该查看

为了回答您的问题,您可能正在考虑使用一个单独的线程,并进行同步调用。另一个线程将阻止等待调用完成


使用APM时,根本没有线程阻塞。线程池中没有抽签。这对于像ASP.NET这样的服务器应用程序尤其重要,因为这意味着阻塞线程不会阻止处理请求。

使用异步调用的优点是不会在I/O上浪费线程阻塞。线程可能会很昂贵,因此在进行大量I/O的情况下,明智地使用线程是关键


也就是说,是的,Begin-End APM很难使用。如果您确实需要非阻塞I/O,并且可以灵活地为应用程序的一部分使用另一种语言,请尝试F#。“异步工作流”让编写异步代码变得轻而易举。

杰夫·里克特(Jeff Richter)有一个非常聪明和干净的方法来使用APM。

我不太明白,你是说一旦我开始APM的“开始操作”,实际上就没有使用任何线程?但“开始操作”的代码实际上在哪里执行呢?此外,“内部操作”回调必须在某个地方执行,如果不是一个单独的线程,那么Begin*代码在调用它的线程上执行,对一些操作进行排队,然后返回。操作完成后,将对池线程调用回调。在开始和回调之间,不使用线程。为何线程在等待时什么也不做;“无线程”也没什么作用。