我需要一些ConcurrentQueue和BlockingCollection的帮助。
该方案是我试图限制请求并符合每秒1个请求的限制,当我从队列中出列项目时将发生限制。该应用程序是一个MVC 4应用程序,因此在任何给定时间都可能有多个生产者,并且我只联系了一个消费者/网络服务。
GetUser(string url)
会向队列添加一个请求,a
请求只是一个网址。简而言之,我想处理队列中的项目,下载响应并将其发送回调用方法。将它发送回调用方法是我陷入困境的地方。我有什么选择?
//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?
}
}
答案 0 :(得分:1)
您可能不希望“返回结果”到ThrottledDown
方法。至少,我不这么认为。如果您确实想这样做,则必须进行某种阻止呼叫。或者使用Task
继续......或者在C#5中使用async
。
目前还不清楚主线程在做什么。我假设它正在排队消费者线程以一秒为间隔处理的一堆请求(可能是为了防止您被要查询的服务器限制)。然后,您需要通知主线程(或其他内容),以便它可以......做某事。
您的计划流程仍不明确。
根据您希望主线程执行的操作(以及您希望它执行此操作的信息),您有许多选项。你可以:
BlockingCollection
个结果。当使用者完成请求时,它会向该集合添加一个对象。主线程轮询该集合以获取请求完成的通知。ManualResetEventSlim
对象添加一个事件(例如Request
)。当消费者完成请求时,消费者会对该事件进行Set
调用。主线程要么等待该事件,要么定期轮询它。Request
对象中传递)。该回调函数可以通知主线程,记录结果或任何你喜欢的内容。同样,如果没有关于您的应用程序的更多信息以及您尝试解决的更高级别问题,则很难提出更具体的建议。