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

egl*_*ius 20 .net c# asynchronous iocp

更新

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

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

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

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

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

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


我一直在努力寻找有关使用IO完成端口的信息.NET.

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

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

更好的是,如果有一些列表使用IOCP的类列表.

Han*_*ant 19

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完成的,那么就不会有替代方案.


usr*_*usr 18

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

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

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

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

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

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

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

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