Update
更新
I asked the wrong question, rephrased (based on the great info on answers and comments):
我问错了问题,改写(根据答案和评论的重要信息):
Is there any good source on .net's async operations being real async, thus either IOCP or async(overlapped)? Is there any quick way to find out if several classes are doing so?
在.net的异步操作是真正的异步,有没有任何好的来源,因此IOCP或异步(重叠)?有没有快速的方法来确定几个类是否这样做?
Example of not trusting framework developers blindly
不盲信任框架开发人员的示例
The natural starting point for creating a FileStream is the static File.Open() method, the documentation for which mentions nothing about synchronicity of the FileStream that is created! Nor does it allow you to provide FileOptions (which are used to specify the magic FileOptions.Asynchronous flag).
创建FileStream的自然起点是静态File.Open()方法,该文档没有提及创建的FileStream的同步性!它也不允许您提供FileOptions(用于指定魔术FileOptions.Asynchronous标志)。
Instead, the FileStream is created with FileOptions.None. Any asynchronous operations are quietly faked by the obliging implementation of the Stream base class, which merely wraps the corresponding synchronous method in a delegate and invokes it on the thread pool using the BeginInvoke() method.
而是使用FileOptions.None创建FileStream。任何异步操作都是由Stream基类的强制实现悄然伪造的,它只是将相应的同步方法包装在委托中,并使用BeginInvoke()方法在线程池上调用它。
This is a deviation from the usual ‘pit of success’ design philosophy, where everything in .NET seems to work as you think it would, without a need to closely read the documentation and/or gradually discover obscure catches and gotchas over time.
这偏离了通常的“成功之坑”设计理念,即.NET中的所有内容似乎都能按照您的想法运行,而无需仔细阅读文档和/或逐渐发现模糊的捕获和陷阱。
I've been trying to find information on the use of IO Completion Ports in .NET
.
我一直在尝试查找有关在.NET中使用IO完成端口的信息。
Is there any good way to know whether a given .NET class is using IO Completion Ports? (without having to run some tests every time you use a new class.
有没有什么好方法可以知道给定的.NET类是否正在使用IO完成端口? (每次使用新类时都不必运行某些测试。
I tried the msdn docs for some classes and methods, and I couldn't find anything on it.
我尝试了msdn文档的一些类和方法,我找不到任何东西。
Even better, would be if there is some list out there with a list of classes using IOCP.
更好的是,如果有一些列表,其中包含使用IOCP的类列表。
2 个解决方案
#1
18
I/O completion ports are a strong platform implementation detail, one that .NET cannot blindly depend on to be available. And it doesn't, it leaves it up to the CLR host to implement the glue to the operating system support for it. The underlying hosting interface is IHostIoCompletionManager, available since .NET 2.0
I / O完成端口是一个强大的平台实现细节,.NET不能盲目依赖可用。它没有,它让CLR主机实现了对操作系统支持的粘合剂。底层托管接口是IHostIoCompletionManager,自.NET 2.0起可用
So if you want a hard guarantee the they actually get used then you need to get the source of the CLR host that you use. This is hard to come by, there are many and you'd need to apply to a job at Microsoft to get access to the source. Only the SSCLI20 host is available in source, it is dated and covers only the default host. Which was itself tweaked to allow the PAL to provide the I/O completion port, surely not actually present in the real CLR hosts you'd ever run on.
因此,如果您想要确保实际使用它们,那么您需要获取您使用的CLR主机的来源。这很难得到,有很多,您需要申请Microsoft的工作才能访问源代码。只有SSCLI20主机在源中可用,它已过时且仅涵盖默认主机。这本身已经过调整,允许PAL提供I / O完成端口,当然不会真正存在于您运行的真实CLR主机中。
You were not specific about what platforms you consider. Some guesstimates:
您没有具体考虑您考虑的平台。一些猜测:
- ASP.NET: yes, I/O completion ports are a big deal for sockets
- ASP.NET:是的,I / O完成端口对于套接字来说是一个大问题
- SQL Server: pretty likely, but no slamdunk, it has a knack for doing things differently
- SQL Server:很可能,但没有任何冲动,它具有以不同方式做事的诀窍
- Desktop: yes, for any .NET version >= 2.0 that runs on the NT branch
- 桌面:是的,对于在NT分支上运行的任何.NET版本> = 2.0
- Compact: definitely not
- 紧凑:绝对不是
- Micro: definitely not
- 微:绝对不是
- XBox: unlikely, OS details are a big mystery
- XBox:不太可能,操作系统细节是一个很大的谜团
- Silverlight: Windows version's CoreCLR.dll uses it but no ThreadPool.BindHandle
- Silverlight:Windows版本的CoreCLR.dll使用它但没有ThreadPool.BindHandle
- Phone7: similar to Silverlight
- Phone7:类似于Silverlight
- Phone8: big mystery, probably.
- Phone8:可能是个大谜。
Emphasizing that these are merely educated guesses that are not backed by proof. The question is otherwise fairly strange, it is not like you'd have an alternative if you find out that async I/O was done by overlapped I/O.
强调这些仅仅是受过教育的猜测,没有证据支持。问题是相当奇怪的,如果你发现异步I / O是由重叠的I / O完成的,那就不像你有另一种选择。
#2
18
Generally, the BCL only offers async APIs if they are implemented using async IO backed by the Windows kernel. Exposing async methods that do not use async kernel-IO would be the well-known async-over-sync anti-pattern which the BCL designers are surely aware of. This would not only be useless, but harmful for performance and misleading. They don't do that.
通常,如果使用Windows内核支持的异步IO实现BCL,则它们仅提供异步API。暴露不使用异步内核IO的异步方法将是众所周知的异步同步反模式,BCL设计人员肯定知道这种反模式。这不仅没用,而且对性能和误导性有害。他们不这样做。
Windows can do async IO using IOCP or using regular overlapped IO. Both are efficient, asynchronous and therefore more scalable than blocking IO.
Windows可以使用IOCP或使用常规重叠IO执行异步IO。两者都是高效的,异步的,因此比阻塞IO更具可扩展性。
All of this is transparent to you. Rely on async being truly async, and sync being truly sync.
所有这些对你来说都是透明的。依赖async是真正的异步,同步是真正的同步。
If in doubt, peek under the hood with Reflector. Whenever I have done this I have found confirmed what I just stated. I have yet to see a deviating case.
如果有疑问,请使用Reflector窥视引擎盖。每当我这样做,我都发现了我刚才所说的。我还没有看到一个偏离的情况。
What you see with Reflector is that the BCL is calling the async versions of the relevant Win32 APIs. As an example, I'll examine files and sockets:
您在Reflector中看到的是BCL正在调用相关Win32 API的异步版本。作为一个例子,我将检查文件和套接字:
-
FileStream.BeginRead
indirectly callsWin32Native.ReadFileNative
with a pointer to aNativeOverlapped
structure. The pointer is obtained by callingOverlapped.Pack
. The completion callback is stored that way. It is impossible to track how the callback is called with Reflector because that part exists in the native part of the CLR. I cannot tell whether IOCP is in use but I can tell that async IO is in use. - FileStream.BeginRead使用指向NativeOverlapped结构的指针间接调用Win32Native.ReadFileNative。通过调用Overlapped.Pack获得指针。完成回调以这种方式存储。无法跟踪如何使用Reflector调用回调,因为该部分存在于CLR的本机部分中。我无法判断IOCP是否正在使用,但我可以判断async IO正在使用中。
-
Socket.BeginRead
indirectly callsWSARecv
. The code is quite complex. The BCL seems to be able to use overlapped IO as well as IOCP depending on the OS. The check is made inSocket.InitializeSockets
. The decision what kind of IO to use is stored inSocket.UseOverlappedIO
. If that variable is false,Socket.BindToCompletionPort
is eventually called. - Socket.BeginRead间接调用WSARecv。代码非常复杂。 BCL似乎能够使用重叠IO以及IOCP,具体取决于操作系统。检查在Socket.InitializeSockets中进行。决定使用哪种IO存储在Socket.UseOverlappedIO中。如果该变量为false,则最终调用Socket.BindToCompletionPort。
So for Sockets it is clearly IOCP on modern OS'es. For files I cannot tell.
所以对于套接字来说,它显然是现代操作系统上的IOCP。对于我无法分辨的文件。
I personally am not particularly interested in what kind of async IO is used as long as it is non-blocking. This is the case.
我个人对使用什么样的异步IO并不特别感兴趣,只要它是非阻塞的。情况就是这样。
#1
18
I/O completion ports are a strong platform implementation detail, one that .NET cannot blindly depend on to be available. And it doesn't, it leaves it up to the CLR host to implement the glue to the operating system support for it. The underlying hosting interface is IHostIoCompletionManager, available since .NET 2.0
I / O完成端口是一个强大的平台实现细节,.NET不能盲目依赖可用。它没有,它让CLR主机实现了对操作系统支持的粘合剂。底层托管接口是IHostIoCompletionManager,自.NET 2.0起可用
So if you want a hard guarantee the they actually get used then you need to get the source of the CLR host that you use. This is hard to come by, there are many and you'd need to apply to a job at Microsoft to get access to the source. Only the SSCLI20 host is available in source, it is dated and covers only the default host. Which was itself tweaked to allow the PAL to provide the I/O completion port, surely not actually present in the real CLR hosts you'd ever run on.
因此,如果您想要确保实际使用它们,那么您需要获取您使用的CLR主机的来源。这很难得到,有很多,您需要申请Microsoft的工作才能访问源代码。只有SSCLI20主机在源中可用,它已过时且仅涵盖默认主机。这本身已经过调整,允许PAL提供I / O完成端口,当然不会真正存在于您运行的真实CLR主机中。
You were not specific about what platforms you consider. Some guesstimates:
您没有具体考虑您考虑的平台。一些猜测:
- ASP.NET: yes, I/O completion ports are a big deal for sockets
- ASP.NET:是的,I / O完成端口对于套接字来说是一个大问题
- SQL Server: pretty likely, but no slamdunk, it has a knack for doing things differently
- SQL Server:很可能,但没有任何冲动,它具有以不同方式做事的诀窍
- Desktop: yes, for any .NET version >= 2.0 that runs on the NT branch
- 桌面:是的,对于在NT分支上运行的任何.NET版本> = 2.0
- Compact: definitely not
- 紧凑:绝对不是
- Micro: definitely not
- 微:绝对不是
- XBox: unlikely, OS details are a big mystery
- XBox:不太可能,操作系统细节是一个很大的谜团
- Silverlight: Windows version's CoreCLR.dll uses it but no ThreadPool.BindHandle
- Silverlight:Windows版本的CoreCLR.dll使用它但没有ThreadPool.BindHandle
- Phone7: similar to Silverlight
- Phone7:类似于Silverlight
- Phone8: big mystery, probably.
- Phone8:可能是个大谜。
Emphasizing that these are merely educated guesses that are not backed by proof. The question is otherwise fairly strange, it is not like you'd have an alternative if you find out that async I/O was done by overlapped I/O.
强调这些仅仅是受过教育的猜测,没有证据支持。问题是相当奇怪的,如果你发现异步I / O是由重叠的I / O完成的,那就不像你有另一种选择。
#2
18
Generally, the BCL only offers async APIs if they are implemented using async IO backed by the Windows kernel. Exposing async methods that do not use async kernel-IO would be the well-known async-over-sync anti-pattern which the BCL designers are surely aware of. This would not only be useless, but harmful for performance and misleading. They don't do that.
通常,如果使用Windows内核支持的异步IO实现BCL,则它们仅提供异步API。暴露不使用异步内核IO的异步方法将是众所周知的异步同步反模式,BCL设计人员肯定知道这种反模式。这不仅没用,而且对性能和误导性有害。他们不这样做。
Windows can do async IO using IOCP or using regular overlapped IO. Both are efficient, asynchronous and therefore more scalable than blocking IO.
Windows可以使用IOCP或使用常规重叠IO执行异步IO。两者都是高效的,异步的,因此比阻塞IO更具可扩展性。
All of this is transparent to you. Rely on async being truly async, and sync being truly sync.
所有这些对你来说都是透明的。依赖async是真正的异步,同步是真正的同步。
If in doubt, peek under the hood with Reflector. Whenever I have done this I have found confirmed what I just stated. I have yet to see a deviating case.
如果有疑问,请使用Reflector窥视引擎盖。每当我这样做,我都发现了我刚才所说的。我还没有看到一个偏离的情况。
What you see with Reflector is that the BCL is calling the async versions of the relevant Win32 APIs. As an example, I'll examine files and sockets:
您在Reflector中看到的是BCL正在调用相关Win32 API的异步版本。作为一个例子,我将检查文件和套接字:
-
FileStream.BeginRead
indirectly callsWin32Native.ReadFileNative
with a pointer to aNativeOverlapped
structure. The pointer is obtained by callingOverlapped.Pack
. The completion callback is stored that way. It is impossible to track how the callback is called with Reflector because that part exists in the native part of the CLR. I cannot tell whether IOCP is in use but I can tell that async IO is in use. - FileStream.BeginRead使用指向NativeOverlapped结构的指针间接调用Win32Native.ReadFileNative。通过调用Overlapped.Pack获得指针。完成回调以这种方式存储。无法跟踪如何使用Reflector调用回调,因为该部分存在于CLR的本机部分中。我无法判断IOCP是否正在使用,但我可以判断async IO正在使用中。
-
Socket.BeginRead
indirectly callsWSARecv
. The code is quite complex. The BCL seems to be able to use overlapped IO as well as IOCP depending on the OS. The check is made inSocket.InitializeSockets
. The decision what kind of IO to use is stored inSocket.UseOverlappedIO
. If that variable is false,Socket.BindToCompletionPort
is eventually called. - Socket.BeginRead间接调用WSARecv。代码非常复杂。 BCL似乎能够使用重叠IO以及IOCP,具体取决于操作系统。检查在Socket.InitializeSockets中进行。决定使用哪种IO存储在Socket.UseOverlappedIO中。如果该变量为false,则最终调用Socket.BindToCompletionPort。
So for Sockets it is clearly IOCP on modern OS'es. For files I cannot tell.
所以对于套接字来说,它显然是现代操作系统上的IOCP。对于我无法分辨的文件。
I personally am not particularly interested in what kind of async IO is used as long as it is non-blocking. This is the case.
我个人对使用什么样的异步IO并不特别感兴趣,只要它是非阻塞的。情况就是这样。