插座开始连接同步执行.NET CORE 2.2中的回调



我看到了一些意外的行为,尽管不一定会引起问题,我想了解异步套接字编程。

这是关于执行mysocket.beginConnect调用及其对所提供的asynccallback的呼叫。有了一些用于网络通信的testproject,我看到,对于相同的代码,在执行开头连接时,提供的回调有时会被同步调用,有时是异步(BeginConnect已经在完成回调之前返回iasyncresult),而后一种情况是最常见的情况(80% - 90%的案例)。

但是,我无法使用非常简单的测试用例与套接字TCP客户端和服务器通信复制同步回调调用。

我检查了.NET Core 2.2框架的源代码,并看到底层LazyAsyncresult类具有两个构造函数,其中一个构造函数在其构造函数中调用了回调。但是,我没有发现框架使用该构造函数的任何情况。我使用调试器启动的呼叫似乎总是创建一个只有对另一个构造函数的基本构造函数的contextawareresult。在某些测试用例中,我也可以在调试器中清楚地看到,已完成的属性返回true。

任何提示在哪种情况下,此回调是同步称为的,为什么?

欢呼。

编辑:

  • 测试发生在Windows 10上。
  • 全框架上的完全相同的代码.NET 4.6.2创建总是异步的。

您尚未指定用于测试的操作系统,但假设当它是窗口时的情况(对于非窗户,我会高度确信该行为应该相似)异步I/O操作的预期行为。特别是不能保证异步的I/O请求总是异步完成。如果有明显的原因,I/O管理器可能会尝试缩短I/O操作路径(一个很好的例子是快速的I/O操作,这些操作绕过典型的I/O通过设备驱动程序流动并直接与Memory Manager通信 - 这主要是为了可以兑现的文件操作)。在这种情况下,无论该操作被请求为异步,结果都可以在同一线程中返回。对于网络i/o,最常遇到此行为的读取操作(对于已经读取到内部缓冲区中的数据时),对于写操作而言,较少的频率(对于TCP,主要是用于Nagle或延迟ACK的情况下,在完成时打开了。输出操作不需要等待ACK数据包)。至于打开TCP连接的场景,当TCP握手过程省略了网络层时,例如Sio_loopback_fast_path option(有关更多详细信息,请参见此处),但仅用于loopback(local -host)接口座点。

.NET I/O异步建立在天然I/O机制的顶部,并继承这些机制的性能和行为。

最新更新