请考虑以下控制台应用程序:
public static void Request(string url)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
var request = WebRequest.Create(url);
request.Timeout = 5000;
request.GetResponse();
}
catch (Exception e)
{
Console.Out.WriteLine(e);
}
Console.Out.WriteLine(url);
});
}
static void Main(string[] args)
{
Request("http://google.com?q=a");
Request("http://google.com?q=b");
Request("http://google.com?q=c");
Request("http://google.com?q=d");
Thread.Sleep(20000);
Console.In.ReadLine();
}
输出将完成2个网址。但对于其余部分,它将抛出“操作已经超时”。 我知道默认情况下并行连接的限制设置为2。如果我将它增加到3,那么三个将完成。 即:
ServicePointManager.DefaultConnectionLimit = 3;
但我的问题是 - 为什么其余的人没有完成,但投掷操作已经超时了?
答案 0 :(得分:3)
因为超时包括进程排队等待连接可用的时间。
代表&#34的超时时间我打电话给GetResponse()
以获得我的回复" 不是"我想要等待最多5000毫秒在GetResponse()
等待无限量的时间在队列中轮流后,最多等待5000毫秒。"
现在,你想知道,"但是查询非常快,完成时间不应超过5000毫秒!"。问题来自于您没有关闭GetResponse的响应,from the MSDN:
您必须调用Close方法关闭流并释放 连接。如果不这样做可能会导致您的申请用完 连接。
调用Dispose()
隐式调用Close()
,因此如果您更新代码以处理您的响应,那么已使用的连接将被释放,其中一个等待请求将能够启动。 / p>
public static void Request(string url)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
var request = WebRequest.Create(url);
request.Timeout = 5000;
using(var response = request.GetResponse())
{
Console.Out.WriteLine("Response - " + url);
}
}
catch (Exception e)
{
Console.Out.WriteLine(e);
}
Console.Out.WriteLine("Method End - " + url);
});
}
static void Main(string[] args)
{
Request("http://google.com?q=a");
Request("http://google.com?q=b");
Request("http://google.com?q=c");
Request("http://google.com?q=d");
Thread.Sleep(20000);
Console.In.ReadLine();
}