C# 使HttpWebRequest调用与C中的Threading.Tasks并行#
在C#(我使用mono在Ubuntu中编译)中并行执行HttpWebRequest调用和Threading.Tasks有什么问题吗? 当我同步向Google发出25个GET请求时,总共需要2-3秒。当我进行异步调用时,需要超过13秒。我的代码:C# 使HttpWebRequest调用与C中的Threading.Tasks并行#,c#,multithreading,httpwebrequest,task,C#,Multithreading,Httpwebrequest,Task,在C#(我使用mono在Ubuntu中编译)中并行执行HttpWebRequest调用和Threading.Tasks有什么问题吗? 当我同步向Google发出25个GET请求时,总共需要2-3秒。当我进行异步调用时,需要超过13秒。我的代码: using System; using System.Net; using System.Diagnostics; using System.Threading.Tasks; public class Google { public stati
using System;
using System.Net;
using System.Diagnostics;
using System.Threading.Tasks;
public class Google
{
public static void Main(string[] args)
{
Stopwatch timer1 = new Stopwatch();
timer1.Start();
for(int i=1; i<=25; i++){
googleit();
}
timer1.Stop();
TimeSpan timeTaken1 = timer1.Elapsed;
Stopwatch timer2 = new Stopwatch();
timer2.Start();
int TaskCount = 25;
var tasks = new Task[TaskCount];
for (var index = 0; index < TaskCount; index++)
{
tasks[index] = Task.Factory.StartNew(googleit);
}
Task.WaitAll(tasks);
timer2.Stop();
TimeSpan timeTaken2 = timer2.Elapsed;
Console.WriteLine("Sync time: ");
Console.WriteLine(timeTaken1);
Console.WriteLine("async time: ");
Console.WriteLine(timeTaken2);
}
private static void googleit(){
Stopwatch timer = new Stopwatch();
timer.Start();
HttpWebRequest request = WebRequest.Create("http://www.google.com") as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();
timer.Stop();
TimeSpan timeTaken = timer.Elapsed;
Console.WriteLine(timeTaken);
}
}
使用系统;
Net系统;
使用系统诊断;
使用System.Threading.Tasks;
公共类谷歌
{
公共静态void Main(字符串[]args)
{
秒表计时器1=新秒表();
timer1.Start();
对于(int i=1;i这应该可以满足您的需要:
public static void SendAsync()
{
int TaskCount = 8;
var tasks = Enumerable.Range(0, TaskCount).Select(p => googleit());
Task.WhenAll(tasks).Wait();
}
private static async Task googleit()
{
HttpWebRequest request = WebRequest.Create("http://www.google.com") as HttpWebRequest;
request.Credentials = CredentialCache.DefaultCredentials;
var response = await request.GetResponseAsync();
response.Close();
}
它将异步发送所有请求,并等待(阻塞)
在您的代码中,您只是为每个请求创建了一个任务。因此,例如,如果您有两个核心,并且TPL决定在两个线程之间拆分所有任务,那么您将有两个线程同步发送请求。在一个核心上,您将有完全同步的执行。
在上面的代码中,您有一个线程以异步方式发送所有请求,也就是说,它发布一个请求并继续发送下一个请求,而无需等待前一个请求返回。在发送所有请求之后,它会阻塞线程,直到继续执行为止-在您的情况下是响应。Close()“-完成。在开始时,在任何事情之前尝试ServicePointManager.DefaultConnectionsLimit=500;
。而且最明显的是不要使用控制台测试性能。其中的WriteLine
。googleit()
应该有4行长。“异步”代码实际上并没有发出异步请求。它正在加速发出同步请求的任务。将其更改为使用request.GetRequestAsync()
而不是Task.Factory.StartNew()
。同意该代码是执行异步请求的错误方法。此外,您应该扩展计时代码,以便在同步和异步情况下都可以看到每个请求需要多长时间。可能大多数请求都很快完成,但在某个时间点,一个(或几个)需要很长时间。可能不会,但您应该确定是否要调试此问题。值得一提的是,我无法重现您描述的问题。我的电脑上的同步版本需要5.7秒,而异步版本需要1.5秒。Windows 8.1。您仍然应该修复代码,使其执行真正的异步I/O,而不是震荡rrent同步操作,但实际上似乎没有任何代码本身导致延迟。可能您的ISP只是在限制您,也可能是Google限制了您,因为您在高峰期测试代码(我现在是深夜)。