阅读本文后指出:
设备完成其作业后(IO操作) - 它通过中断通知CPU.
...... ......
但是,"完成"状态仅存在于操作系统级别; 该进程有自己的内存空间,必须通知
...... ......
由于库/ BCL使用标准的P/Invoke重叠I/O系统,因此它已经使用I/O完成端口(IOCP)注册了句柄,IOCP是线程池的一部分.
...... ......
因此,简单地借用 I/O线程池线程来执行APC,APC通知任务它已完成.
关于大胆的部分,我很有趣:
如果我理解正确,在IO操作完成后,它必须通知执行IO操作的实际进程.
问题#1:
这是否意味着它为每个完成的IO操作抓取一个新的线程池线程?或者这是一个专门的线程数?
问题2:
看着 :
for (int i=0;i<1000;i++)
{
PingAsync_NOT_AWAITED(i); //notice not awaited !
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着我将同时运行1000个IOCP线程池线程(某种类型),当它们全部完成时?
AFAIK .Net库中的一些方法能够异步执行I/O作业而不消耗池中的线程.
如果我的信息是正确的,WebClient*Async方法就是这样做的.
我想通过检查下载过程中是否有效地使用池中的线程来验证它.
所以我的一般问题是:如何监控线程池的当前状态?
线程数
忙线程数
是否有一些API(GetAvailableThreads?)或性能计数器可以提供此信息?
编辑:这里有一些更多的细节
我正在为教育目的写一个简单的基准:
string[] urls = Enumerable.Repeat("http://google.com", 32).ToArray();
/*{
"http://google.com",
"http://yahoo.com",
"http://microsoft.com",
"http://wikipedia.com",
"http://cnn.com",
"http://facebook.com",
"http://youtube.com",
"http://twitter.com"
};*/
/*Task.Run(() =>
{
while (true)
{
int wt, cpt;
ThreadPool.GetAvailableThreads(out wt, out cpt);
Console.WriteLine("{0} / {1}", wt, cpt);
Thread.Sleep(100);
}
});*/
WebClient webClient = new WebClient();
Stopwatch stopwatch = Stopwatch.StartNew();
foreach (string url in urls)
{
webClient.DownloadString(url);
Console.WriteLine("Got '{0}'", url);
}
stopwatch.Stop(); …Run Code Online (Sandbox Code Playgroud) 我的理解是,如果我使用异步,线程会发出Web请求并继续前进.当响应返回时,另一个线程从那里拾取它.因此,有较少数量的捆绑线程处于空闲状态.这不意味着最大活线程数会下降吗?但在下面的示例中,不使用异步的代码最终使用较少数量的线程.有人可以解释为什么吗?
没有异步的代码(使用较小的线程):
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
namespace NoAsync
{
internal class Program
{
private const int totalCalls = 100;
private static void Main(string[] args)
{
for (int i = 1; i <= totalCalls; i++)
{
ThreadPool.QueueUserWorkItem(GoogleSearch, i);
}
Thread.Sleep(100000);
}
private static void GoogleSearch(object searchTerm)
{
Thread.CurrentThread.IsBackground = false;
string url = @"https://www.google.com/search?q=" + searchTerm;
Console.WriteLine("Total number of threads in use={0}", Process.GetCurrentProcess().Threads.Count);
WebRequest wr = WebRequest.Create(url);
var httpWebResponse = (HttpWebResponse) wr.GetResponse();
var reader = …Run Code Online (Sandbox Code Playgroud)