C# 为什么赢了';我的.net应用程序是否同时发出10个以上的WebClient请求?

C# 为什么赢了';我的.net应用程序是否同时发出10个以上的WebClient请求?,c#,asynchronous,webclient,threadpool,async-await,C#,Asynchronous,Webclient,Threadpool,Async Await,我试图理解C#中异步/等待和Windows中I/O完成端口的复杂性,编写代码来验证我的假设 据我所知,调用WebClient.DownloadStringTaskAsync(…)将使当前线程使用I/O完成端口注册I/O操作(这可能有点模糊,我还不了解细节),它将创建一个任务,并将继续执行代码。在某个时刻,它将遇到一个等待的给定任务。在这一点上,它将从当前方法返回(好吧,它将退出某个范围,我不确定这个范围是否可以是一个方法以外的东西-我可能应该检查生成的状态机以了解该部分)。一旦I/O操作完成,将

我试图理解C#中异步/等待和Windows中I/O完成端口的复杂性,编写代码来验证我的假设

据我所知,调用
WebClient.DownloadStringTaskAsync(…)
将使当前线程使用I/O完成端口注册I/O操作(这可能有点模糊,我还不了解细节),它将创建一个
任务
,并将继续执行代码。在某个时刻,它将遇到一个
等待
的给定任务。在这一点上,它将从当前方法返回(好吧,它将退出某个范围,我不确定这个范围是否可以是一个方法以外的东西-我可能应该检查生成的状态机以了解该部分)。一旦I/O操作完成,将从线程池抓取一个线程,它将被传递I/O操作的结果,并将执行刚才提到的其余范围

我已经尝试过验证这种行为,但在某些事情似乎不正确之前,我只得到了这段C#代码:

class Program
{
    static void Main(string[] args)
    {
        ThreadPool.SetMaxThreads(30, 30);
        Console.WriteLine("Connection limit is {0}", ServicePointManager.DefaultConnectionLimit);
        for (int i = 0; i < 30; i++)
        {
            FetchAsync(i);
        }

        Console.WriteLine("Done starting requests");
        Console.ReadKey();
    }

    private async static void FetchAsync(int num)
    {
        WebClient wc = new WebClient();
        string result = await wc.DownloadStringTaskAsync("http://localhost/slow/index/15");
        Console.WriteLine("Done #{0}", num);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
线程池.SetMaxThreads(30,30);
WriteLine(“连接限制为{0}”,ServicePointManager.DefaultConnectionLimit);
对于(int i=0;i<30;i++)
{
FetchAsync(i);
}
Console.WriteLine(“完成启动请求”);
Console.ReadKey();
}
私有异步静态void FetchAsync(int num)
{
WebClient wc=新的WebClient();
字符串结果=等待wc.DownloadStringTaskAsync(“http://localhost/slow/index/15");
WriteLine(“Done{0}”,num);
}
}
如您所见,我正在使用
WebClient
为一个网页创建30个请求(我知道这很慢,需要15秒才能响应)。运行此代码时,我观察到以下行为:15秒后,前10个请求完成。再过15秒,10个请求完成,再过15秒,其余请求完成。因此,一次似乎只有10个未完成的请求(使用perfmon,我已经验证了正在调用的web应用程序有10个当前请求)。为什么呢?我预计会有30个并发请求,因为我已经按照上面的代码设置了线程池的最大线程数

让我相信
ServicePointManager
可能与此有关,但由于
DefaultConnectionLimit
仅为2,因此我认为没有连接

我意识到这是一个相当简单问题的冗长描述。我希望这能让别人更容易指出我的假设到底哪里是错的


我正在Windows 7 64位计算机上运行此程序。

您的客户端可以发送任意多个并发请求。但是,您的服务器是本地主机。客户端Windows操作系统对web应用程序中并发请求的数量有限制(因此您必须购买服务器许可证)。这个限制是10。你对此无能为力


顺便说一句,您的应用程序正在使用异步IO,因此在IO运行时,您不需要任何线程(甚至不需要隐式线程池线程)。这不是您的问题。

您是在Windows服务器操作系统上运行此功能,还是在客户端操作系统(如Win 7)上运行此功能?在客户端windows版本中,网络活动通常会受到限制。感谢您的评论。我更新了问题:我在64位Thinkpad上运行Windows7。您知道这些限制是否可以更改(或至少可以检查)?嗯,您可以检查windows日志中的事件ID 4228吗?我最初指的是一个限制,防止人们在文件服务器上使用客户端操作系统。还没有看到这一点得到证实,但在谷歌上我找到了我刚刚发布的链接。所以它可能完全不同。@Rune TPL还试图优化您使用的线程数量。只要试着使用纯
Thread
类就可以了。我可以有比池中线程更多的未完成请求,这正是我在遇到上述行为时试图演示的。不管怎样,现在一切都有意义了。当我在WS2008上运行它时,ServicePoint.ConnectionLimit开始生效。当我提出这个问题时,我可以得到我想要的任何数量的未完成的请求。谢谢,非常感谢。