假设我调用了HttpWebRequest.BeginGetRequestStream()方法。
我知道这个方法是异步的,当它完成时,应该调用一个回调方法。
我非常确定在调用回调方法时,CLR会创建一个I / O线程,而这个I / O线程会进行回调。
当我调用HttpWebRequest.BeginGetRequestStream()时,我不确定,CLR是否创建了任何I / O线程?或者只创建一个工作线程来将请求发送到设备?
答案 0 :(得分:3)
Async IO is thread-less.没有创建或阻止任何线程。这是使用异步IO的全部意义!你可以帮助你解锁一个线程并阻止另一个线程吗?
已经多次讨论了这种内部结构。基本上,操作系统在IO完成时通知CLR。这会导致CLR将您指定的完成回调排队到线程池中。
答案 1 :(得分:1)
简短回答:你不在乎。
答案很长:
没有线程。更确切地说,您创建的每个异步请求都没有线程。相反,线程池上有一堆I / O线程,主要是"等待"在IOCP上 - 等待内核在数据可用时将其唤醒。
重要的一点是,这些中的每一个都可以响应任何通知,它们(必然)没有选择性。如果你需要处理1000个响应,你仍然可以只使用一个线程 - 而且只是在此时才请求来自线程池的线程;它必须执行回调方法。例如,使用同步方法,您必须保留一千个线程来处理一千个TCP连接。
使用异步方法,您只需要一个IOCP线程,并且您只需要生成(或者更确切地说,借用)新线程来执行回调 - 这些回调仅在您获得新数据/连接之后执行,并且一旦你完成,就会返回到线程池。实际上,这意味着TCP服务器只需少量线程即可处理数千个并发TCP连接。毕竟,产生更多的线程比你的CPU能够处理更多的线程(这些天通常是你拥有内核的两倍),以及所有不需要的东西CPU(如异步I / O)不要求您生成新线程。如果少数处理线程不够,添加更多线程将无助于,与同步I / O场景不同。