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 个请求并将响应转储到同一个线程中。

您能否给我任何可能的方法的指示。

4

3 回答 3

2

您可以利用Task.NET 4.0 和新玩具HttpClient,下面的示例代码显示了您如何并行发送请求,然后使用以下方法在同一线程中转储响应ContinueWith

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

任务ThreadPool在后台使用,因此您无需指定应该使用多少线程,ThreadPool将以优化的方式为您管理。

于 2013-02-05T16:35:41.763 回答
1

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

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

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

于 2013-02-05T16:40:14.780 回答
0

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

伪代码将类似于:

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

    }
  });

也许 aBlockingCollection可能会更好地为您服务,具体取决于您希望如何同步线程以发出传入请求结束的信号。

于 2013-02-05T16:36:31.573 回答