在哪里/如何找到.net类是否使用IOCP?

更新

我问错了问题,改写(根据答案和评论的重要信息):

在.net的异步操作是真正的异步,有没有任何好的来源,因此IOCP或异步(重叠)? 有没有快速的方法来确定几个类是否这样做?

不盲信任框架开发人员的示例

创建FileStream的自然起点是静态File.Open()方法,该文档没有提及创建的FileStream的同步性! 它也不允许您提供FileOptions(用于指定魔术FileOptions.Asynchronous标志)。

而是使用FileOptions.None创建FileStream。 任何异步操作都是由Stream基类的强制实现悄然伪造的,它只是将相应的同步方法包装在委托中,并使用BeginInvoke()方法在线程池上调用它。

这偏离了通常的“成功之坑”设计理念,即.NET中的所有内容似乎都能按照您的想法运行,而无需仔细阅读文档和/或逐渐发现模糊的捕获和陷阱。


我一直在尝试查找有关在.NET使用IO完成端口的信息。

有没有什么好方法可以知道给定的.NET类是否正在使用IO完成端口 ? (每次使用新类时都不必运行某些测试。

我尝试了msdn文档的一些类和方法,我找不到任何东西。

更好的是,如果有一些列表,其中包含使用IOCP的类列表。

I / O完成端口是一个强大的平台实现细节,.NET不能盲目依赖可用。 它没有,它让CLR主机实现了对操作系统支持的粘合剂。 底层托管接口是IHostIoCompletionManager ,自.NET 2.0起可用

因此,如果您想要确保实际使用它们,那么您需要获取您使用的CLR主机的来源。 这很难得到,有很多,您需要申请Microsoft的工作才能访问源代码。 只有SSCLI20主机在源中可用,它已过时且仅涵盖默认主机。 这本身已经过调整,允许PAL提供I / O完成端口,当然不会真正存在于您运行的真实CLR主机中。

您没有具体考虑您考虑的平台。 一些猜测:

  • ASP.NET:是的,I / O完成端口对于套接字来说是一个大问题
  • SQL Server:很可能,但没有任何冲动,它具有以不同方式做事的诀窍
  • 桌面:是的,对于在NT分支上运行的任何.NET版本> = 2.0
  • 紧凑:绝对不是
  • 微:绝对不是
  • XBox:不太可能,操作系统细节是一个很大的谜团
  • Silverlight:Windows版本的CoreCLR.dll使用它但没有ThreadPool.BindHandle
  • Phone7:类似于Silverlight
  • Phone8:可能是个大谜。

强调这些仅仅是受过教育的猜测,没有证据支持。 问题是相当奇怪的,如果你发现异步I / O是由重叠的I / O完成的,那就不像你有另一种选择。

通常,如果使用Windows内核支持的异步IO实现BCL,则它们仅提供异步API。 暴露不使用异步内核IO的异步方法将是众所周知的异步同步反模式,BCL设计人员肯定知道这种反模式。 这不仅没用,而且对性能和误导性有害。 他们不这样做。

Windows可以使用IOCP或使用常规重叠IO执行异步IO。 两者都是高效的,异步的,因此比阻塞IO更具可扩展性。

所有这些对你来说都是透明的。 依赖async是真正的异步,同步是真正的同步。

如果有疑问,请使用Reflector窥视引擎盖。 每当我这样做,我都发现了我刚才所说的。 我还没有看到一个偏离的情况。

您在Reflector中看到的是BCL正在调用相关Win32 API的异步版本。 作为一个例子,我将检查文件和套接字:

  • FileStream.BeginRead使用指向NativeOverlapped结构的指针间接调用Win32Native.ReadFileNative 。 通过调用Overlapped.Pack获得指针。 完成回调以这种方式存储。 无法跟踪如何使用Reflector调用回调,因为该部分存在于CLR的本机部分中。 我无法判断IOCP是否正在使用,但我可以判断async IO正在使用中。
  • Socket.BeginRead间接调用WSARecv 。 代码非常复杂。 BCL似乎能够使用重叠IO以及IOCP,具体取决于操作系统。 检查在Socket.InitializeSockets 。 决定使用哪种IO存储在Socket.UseOverlappedIO 。 如果该变量为false,则最终调用Socket.BindToCompletionPort

所以对于套接字来说,它显然是现代操作系统上的IOCP。 对于我无法分辨的文件。

我个人对使用什么样的异步IO并不特别感兴趣,只要它是非阻塞的。 情况就是这样。