返回调用方法- BlockingCollection队列项
本文关键字:队列 BlockingCollection 调用 方法 返回 | 更新日期: 2023-09-27 18:06:00
我需要一些ConcurrentQueue's和BlockingCollection的帮助。
这个场景是我试图限制请求并遵循每秒1个请求的限制,当我从队列中取出一个项目时将发生限制。这个应用程序是一个MVC 4应用程序,所以在任何给定的时间都可能有多个生产者,而我只联系一个消费者/web服务。
- 生产者
GetUser(string url)
将添加一个请求到队列,a请求只是一个url。 - 通过执行一些检查来处理BlockingCollection中的第一项,以确保它不违反限制。
- 从用户下载响应 然后以某种方式将下载响应返回给调用方法。ThrottledDownload
简而言之,我想处理队列中的一个项目,下载响应并将其发送回调用方法。将它发送回调用方法是我卡住的地方。我有什么选择?
//I want to do something like this, and wait for the throttled response to return
public class WebService()
{
public string GetUser(string name)
{
var url = buildUrl(name);
var response = string.Empty;
var downloadTask = Task.Factory.StartNew( () => {
response = WebServiceHelper.ThrottledDownload(url);
});
downloadTask.Wait();
return response;
}
}
public static class WebServiceHelper()
{
private static BlockingCollection<Request> requests = new BlockingCollection<Request>();
static WebServiceHelper()
{
foreach(var item in requests.GetEnumerableConsumer()) {
string response = DoWork(item.Url);
//How can i send this back to the calling method?
}
}
public static string ThrottledDownload(string url)
{
//Add the request to the blocking queue
requests.Add(new Request(url, someId));
//How do i get the result of the DoWork method?
}
}
您可能不想向ThrottledDown
方法"返回一个结果"。至少,我不这么认为。如果你真想这么做,你就得打个屏蔽电话。或者使用连续的Task
…可能是c# 5中的async
。
目前还不清楚主线程在做什么。我假设它是以一秒钟的间隔对一堆请求进行排队(大概是为了防止您被您正在查询的服务器限制)。然后,您希望主线程(或其他东西)得到通知,以便它可以…做点什么。
程序的流程还不清楚。
根据你想让主线程做什么(以及你想让它做什么信息),你有很多选择。您可以:
- 创建另一个
BlockingCollection
结果。当使用者完成请求时,它向该集合添加一个对象。主线程轮询该集合以获得请求完成的通知。 - 上面的一个变体是使用管道。一个线程对请求进行排队。一个线程退出请求队列,发出Web请求,然后将结果放入另一个队列。第三个线程处理第二个队列。
- 为每个
Request
对象添加一个事件(例如ManualResetEventSlim
)。消费者在完成请求后调用该事件的Set
。主线程要么等待该事件,要么定期轮询。 - 让消费者执行回调函数(在编译时定义,或者在添加到队列的
Request
对象中传递)。这个回调函数可以通知主线程,记录结果,或者任何你喜欢的。
同样,如果没有更多关于您的应用程序和您试图解决的更高级别问题的信息,则很难提出更具体的建议。