在哪里/如何找到.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并不特别感兴趣,只要它是非阻塞的。 情况就是这样。