据说,BeginReceive
和BeginSend
回调未在.Net ThreadPool
上执行,而是在IOCP ThreadPool
上执行。对于高性能服务器,IOCP线程尽快返回池是至关重要的,这意味着BeginReceive
和BeginSend
的回调中没有重大提升。如果我调用异步方法并在回调中等待它,该怎么办?
是否意味着IOCP
线程将返回到线程池,当异步操作完成时,回调方法将继续在另一个可用的IOCP
线程上?
答案 0 :(得分:3)
AFAIK,无法保证这些回调将在IOCP线程上执行。
如果使回调异步并使用await
,则回调线程将返回到线程池(无论是IOCP线程还是常规线程池线程)。稍后,当异步方法恢复时,它将在常规线程池线程上恢复,而不是IOCP线程(AFAIK这是未记录的但只是有意义)。
但是,我无法想象您实际上想要这样做的用例。如果您wrapped BeginReceive
/EndReceive
and BeginSend
/EndSend
within a task-based API并且始终使用async
/ await
,则代码会更清晰。
答案 1 :(得分:2)
如果您拨打await
async
方法,则会使用ThreadPool
主题执行续会(除非SynchronizationContext
或TaskScheduler
另有指定,这不是这种情况。)
但是,除非async
应该避免,否则您无法进行回调async void
。所以我不明白你如何在这个回调中合理await
。
使用BeginX/EndX
将Task
转换为FromAsync
会更加简单,然后您可以通过更多控制来处理它上的延续。例如,您可以指定TaskScheduler.Defaul
t以确保延续在ThreadPool
线程上运行。
var task = Task.Factory.FromAsync(BeginX, EndX,...);
task.ContinueWith(ante => {...}, null, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default)