2013-02-05 128 views
0

我有一个任务,我形成了数千个请求,稍后发送到服务器。服务器返回每个请求的响应,然后将该响应逐行转储到输出文件。使用多线程发送多个请求到服务器

的伪代码是这样的:

//requests contains thousands of requests to be sent to the server 
string[] requests = GetRequestsString(); 


foreach(string request in requests) 
{ 
    string response = MakeWebRequest(request); 
    ParseandDump(response); 
} 

现在,可以看出的发球处理我的请求,一个接一个。我想快速完成整个过程。有问题的服务器能够一次处理多个请求。我想要应用多线程并发送4个请求到服务器,并在同一线程中转储响应。

你能否给我任何指向可能的方法。

+0

这样的事情呢,类似的问题: http://stackoverflow.com/questions/2960056/trying-to-run-multiple-http-requests-in-parallel-but-being-limited-by-windows –

+0

写出回答时,顺序是否重要? – mbeckish

+0

我会看看线程池或任务并行库。这个问题有两种方法很好的讨论:http://stackoverflow.com/questions/5213695/should-i-use-threadpools-or-task-parallel-library-for-io-bound-operations – GrandMasterFlush

回答

2

您可以从.NET 4.0和新的玩具HttpClient,采取Task优势示例代码下面展示了如何在发送并行请求,然后通过使用ContinueWith倾倒在同一个线程响应:

var httpClient = new HttpClient(); 
var tasks = requests.Select(r => httpClient.GetStringAsync(r).ContinueWith(t => 
      { 
       ParseandDump(t.Result); 
      })); 

任务使用ThreadPool,所以你不需要指定应该使用多少个线程,ThreadPool会以优化的方式为你管理。

+1

非常好的一个! :-) – Mithrandir

0

我认为这可以在消费者 - 生产者模式中完成。您可以使用ConcurrentQueue(来自命名空间System.Collections.Concurrent)作为许多并行WebRequests和转储线程之间的共享资源。

的伪代码会是这样的:

var requests = GetRequestsString(); 
var queue = new ConcurrentQueue<string>(); 

Task.Factory.StartNew(() => 
{ 
    Parallel.ForEach(requests , currentRequest => 
    { 
     queue.Enqueue(MakeWebRequest(request)); 
    } 
}); 

Task.Factory.StartNew(() => 
{ 
    while (true) 
    {   
     string response; 
     if (queue.TryDequeue(out response)) 
     { 
      ParseandDump(response); 
     } 

    } 
    }); 

也许BlockingCollection可能有助于你更好,这取决于你想如何去同步线程信号传入的请求的结束。

+0

你正在做消费者方面的忙碌的等待。你使用'BlockingCollection'会得到更好的服务,因为你没有自己做正确的等待。 – Servy

1

最简单的方法是使用Parallel.ForEach这样的:

string[] requests = GetRequestsString(); 
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request))); 

.NET框架4.0或更高版本才能使用Parallel