Async/await 在 BeginReceive 回调中

Async/await within BeginReceive Callback

据说 BeginReceiveBeginSend 回调不会在 .Net ThreadPool 上执行,而是在 IOCP ThreadPool 上执行。对于高性能服务器,IOCP 线程尽快 return 到池中至关重要,这意味着 BeginReceiveBeginSend 的回调中没有繁重的工作。如果我调用异步方法并在回调中等待它会怎样? 这是否意味着 IOCP 线程将 return 到线程池,当异步操作完成时回调方法将在另一个可用的 IOCP 线程上继续?

据我所知,不能保证这些回调会在 IOCP 线程上执行。

如果您使回调异步并使用 await,则回调线程将返回到线程池(无论是 IOCP 线程还是常规线程池线程)。稍后,当异步方法恢复时,它将在常规线程池线程上恢复,而不是 IOCP 线程(据我所知,这没有记录但很有意义)。

但是,我无法想象您实际想要执行此操作的用例。如果您 wrapped BeginReceive/EndReceive and BeginSend/EndSend within a task-based API 并且在整个过程中只使用 async/await,代码会更清晰。

如果您调用 await 一个 async 方法,将使用 ThreadPool 线程执行延续(除非 SynchronizationContextTaskScheduler,这里不是这种情况)。

但是,您不能进行回调 async,除非它是 async void,应该避免。所以我看不出你如何合理地await这个回调中的任何东西。

BeginX/EndX 转换为带有 FromAsyncTask 会简单得多,然后您可以通过更多控制来处理它的延续。例如,您可以指定 TaskScheduler.Default 以确保延续在 ThreadPool 线程上运行。

var task = Task.Factory.FromAsync(BeginX, EndX,...);
task.ContinueWith(ante => {...}, null, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default)