节流/阻止异步http请求

时间:2016-01-12 19:01:45

标签: c# .net multithreading asynchronous producer-consumer

我有许多生产者任务将数据推送到BlockingCollection,我们称之为requestQueue。

我还有一个消费者任务,它会从requestQueue中弹出请求,并将异步http请求转发给远程Web服务。

我需要限制或阻止发送到Web服务的活动请求数。在一些远离服务或互联网连接速度较慢的机器上,http响应时间足够长,以至于活动请求的数量比我想要的更多。

目前我正在使用信号量方法,多次在消费者线程上调用WaitOne,并在HTTP响应回调上调用Release。有更优雅的解决方案吗?

我被绑定到.net 4.0,并且想要一个基于标准库的解决方案。

1 个答案:

答案 0 :(得分:1)

您已使用BlockingCollection为什么要WaitHandle

我这样做的方法是使用BlockingCollection n作为其有限容量,其中n是您希望拥有的最大并发请求数任何给定的时间。

然后你可以做类似......

var n = 4;
var blockingQueue = new BlockingCollection<Request>(n);

Action<Request> consumer = request => 
{
    // do something with request.
};

var noOfWorkers = 4;
var workers = new Task[noOfWorkers];

for (int i = 0; i < noOfWorkers; i++)
{
    var task = new Task(() =>
    {
        foreach (var item in blockingQueue.GetConsumingEnumerable())
        {
            consumer(item);
        }
    }, TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach);
    workers[i] = task;
    workers[i].Start();
}

Task.WaitAll(workers);

我让你负责取消和错误处理但是使用它你也可以控制你想要在任何给定时间有多少工人,如果工人忙于发送和处理请求,任何其他生产者将被阻止,直到更多房间在队列中。