我有一个任务,我会形成数千个请求,这些请求稍后会被发送到服务器。服务器返回每个请求的响应,然后该响应逐行转储到输出文件。
伪代码如下:
//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 :(得分:2)
您可以利用.NET 4.0中的Task
和新玩具HttpClient
,下面的示例代码展示了如何并行发送请求,然后使用{{在同一个线程中转储响应1}}:
ContinueWith
任务使用var httpClient = new HttpClient();
var tasks = requests.Select(r => httpClient.GetStringAsync(r).ContinueWith(t =>
{
ParseandDump(t.Result);
}));
,因此您无需指定应使用多少线程,ThreadPool
将以优化的方式为您管理。
答案 1 :(得分:1)
最简单的方法是使用Parallel.ForEach
,如下所示:
string[] requests = GetRequestsString();
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request)));
使用Parallel
时需要.NET Framework 4.0或更高版本。
答案 2 :(得分:0)
我认为这可以在消费者 - 生产者模式中完成。您可以使用ConcurrentQueue
(来自命名空间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);
}
}
});
也许BlockingCollection
可能会为您提供更好的服务,具体取决于您希望如何同步线程以表示传入请求的结束。