C# 使用多线程向服务器发送多个请求

C# 使用多线程向服务器发送多个请求,c#,multithreading,C#,Multithreading,我有一个任务,我在其中形成数千个请求,这些请求随后被发送到服务器。服务器返回每个请求的响应,然后逐行将该响应转储到输出文件中 伪代码如下所示: //requests contains thousands of requests to be sent to the server string[] requests = GetRequestsString(); foreach(string request in requests) { string response = MakeWebRe

我有一个任务,我在其中形成数千个请求,这些请求随后被发送到服务器。服务器返回每个请求的响应,然后逐行将该响应转储到输出文件中

伪代码如下所示:

//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);
}
string[] requests = GetRequestsString();
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request)));
现在,正如我们所看到的,服务员正在一个接一个地处理我的请求。我想加快整个过程。所讨论的服务器能够一次处理多个请求。我想应用多线程,一次向服务器发送4个请求,并在同一线程中转储响应

您能给我一些可能的方法的指针吗。

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

var httpClient = new HttpClient();
var tasks = requests.Select(r => httpClient.GetStringAsync(r).ContinueWith(t =>
            {
                ParseandDump(t.Result);
            }));
任务在引擎盖下使用
ThreadPool
,因此您无需指定应使用多少线程,
ThreadPool
将以优化的方式为您管理此任务。

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

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

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

我认为这可以在消费者-生产者模式下完成。您可以使用
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);
       }

    }
  });
var requests=GetRequestsString();
var queue=新的ConcurrentQueue();
Task.Factory.StartNew(()=>
{
Parallel.ForEach(请求,currentRequest=>
{
排队(MakeWebRequest(request));
}
});
Task.Factory.StartNew(()=>
{
while(true)
{        
字符串响应;
if(queue.TryDequeue(out响应))
{
ParseandDump(响应);
}
}
});

根据您希望如何同步线程以发出传入请求结束的信号,
BlockingCollection
可能会更好地为您服务。

我认为这可以在消费者-生产者模式中完成。您可以使用
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);
       }

    }
  });
var requests=GetRequestsString();
var queue=新的ConcurrentQueue();
Task.Factory.StartNew(()=>
{
Parallel.ForEach(请求,currentRequest=>
{
排队(MakeWebRequest(request));
}
});
Task.Factory.StartNew(()=>
{
while(true)
{        
字符串响应;
if(queue.TryDequeue(out响应))
{
ParseandDump(响应);
}
}
});

根据您希望如何同步线程以发出传入请求结束的信号,
BlockingCollection
可能会更好地为您服务。

最简单的方法是使用
Parallel。ForEach
如下:

//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);
}
string[] requests = GetRequestsString();
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request)));

.NET framework 4.0或更高版本需要使用
Parallel

最简单的方法是使用
Parallel。ForEach
如下:

//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);
}
string[] requests = GetRequestsString();
Parallel.ForEach(requests, request => ParseandDump(MakeWebRequest(request)));

.NET framework 4.0或更高版本需要使用
并行

类似的问题:我想看看线程池或任务并行库。这个问题对这两种方法都有很好的讨论:写响应时顺序重要吗?类似的问题:我想看看线程池或任务并行库。这个问题对这两种方法都进行了很好的讨论:写响应时顺序重要吗?你在忙着等待消费者。如果使用
阻止集合
,你会得到更好的服务,因为你没有正确地等待你自己。你在忙着等待消费者。如果使用
阻止收集
,你会得到更好的服务,因为你没有自己正确地等待。