使用C#中的Threading.Tasks并行进行HttpWebRequest调用

时间:2015-01-21 20:24:02

标签: c# multithreading httpwebrequest task

在C#中使用Threading.Tasks并行制作HttpWebRequest调用是否存在问题(我使用mono在Ubuntu中编译)? 当我向Google同步发出25个GET请求时,总共需要2-3秒。当我进行异步调用时,它需要超过13秒。我的代码:

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);
    }
}

1 个答案:

答案 0 :(得分:0)

这可以满足您的需求:

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();
}

它将异步发送所有请求,并等待(阻止)。

在您的代码中,您只是为每个请求创建一个任务。因此,如果您有2个内核,并且TPL决定在两个线程之间拆分所有任务,那么您将有两个线程同步发送请求。在一个核心上,您可以完全同步执行。 在上面的代码中,您有一个线程异步发送所有请求,也就是说,它会发送请求并继续发送下一个请求,而不必等待上一个回来。在发送所有请求之后,它会阻止线程直到延续 - 在您的情况下&#39; response.Close()&#39; - 完成了。