在我的申请中
int numberOfTimes = 1; //Or 100, or 100000
//Incorrect, please see update.
var tasks = Enumerable.Repeat(
(new HttpClient()).GetStringAsync("http://www.someurl.com")
, numberOfTimes);
var resultArray = await Task.WhenAll(tasks);
使用numberOfTimes == 1,需要5秒钟。
使用numberOfTimes == 100000,仍需要5秒钟。
太奇怪了。
但这是否意味着我可以并行运行无限制的呼叫?当它开始排队时必须有一些限制吗?
那是什么限制?那套在哪里?它取决于什么?
换句话说,有多少个IO完成端口?谁都在争夺他们? IIS是否拥有自己的IO完成端口集。
- 这是在ASP.Net MVC操作,.Net 4.5.2,IIS
中 击>更新:感谢@Enigmativity,以下与问题
更相关var tasks = Enumerable.Range(1, numberOfTimes ).Select(i =>
(new HttpClient()).GetStringAsync("http://deletewhenever.com/api/default"));
var resultArray = await Task.WhenAll(tasks);
使用numberOfTimes == 1,需要5秒钟。
使用numberOfTimes == 100,它仍需要5秒钟。
我现在看到更多可信的数字用于更高的数量。问题仍然存在,这个数字是什么?
答案 0 :(得分:3)
这是一个测试,看看发生了什么。
从这段代码开始:
var i = 0;
Func<int> generate = () =>
{
Thread.Sleep(1000);
return i++;
};
现在打电话给:
Enumerable.Repeat(generate(), 5)
一秒钟后,您获得{ 0, 0, 0, 0, 0 }
。
但请拨打电话:
Enumerable.Range(0, 5).Select(n => generate())
五秒钟后,您获得{ 0, 1, 2, 3, 4 }
。
它只在代码中调用一次异步函数。
答案 1 :(得分:3)
那是什么限制?那套在哪里?
没有明确的限制。但是,您最终将耗尽资源。 Mark Russinovich有一个有趣的blog series on probing the limits of common resources。
异步操作通常会增加内存使用量以换取响应能力。因此,每个自然异步操作至少使用内存用于其Task
,OVERLAPPED
结构和驱动程序的IRP(每个都表示在不同级别的正在进行的异步操作)。在较低级别,有很多不同的限制可以起到影响系统资源的作用(例如,我有一篇旧的博客文章,我had to calculate the maximum size of an I/O buffer - 你会认为这很简单,但实际上是不是)。
套接字操作需要一个客户端端口,它(理论上)限制为与同一远程IP的64k连接。套接字也有自己更大的内存开销,在设备级和用户空间都有输入和输出缓冲区。
在操作完成之前,IOCP不会发挥作用。在.NET上,您的AppDomain只有一个IOCP。在现代(4.5).NET框架上,为此IOCP提供服务的默认最大I / O线程数为1000。请注意,这是对一次可以完成的操作数量的限制,而不是一次正在进行中的数量
。