返回调用方法 - BlockingCollection队列项

时间:2013-03-26 12:13:20

标签: c# .net-4.0 queue

我需要一些ConcurrentQueue和BlockingCollection的帮助。

该方案是我试图限制请求并符合每秒1个请求的限制,当我从队列中出列项目时将发生限制。该应用程序是一个MVC 4应用程序,因此在任何给定时间都可能有多个生产者,并且我只联系了一个消费者/网络服务。

  • 生产者GetUser(string url)会向队列添加一个请求,a 请求只是一个网址。
  • 通过执行一些检查来处理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?
  } 
}

1 个答案:

答案 0 :(得分:1)

您可能不希望“返回结果”到ThrottledDown方法。至少,我不这么认为。如果您确实想这样做,则必须进行某种阻止呼叫。或者使用Task继续......或者在C#5中使用async

目前还不清楚主线程在做什么。我假设它正在排队消费者线程以一秒为间隔处理的一堆请求(可能是为了防止您被要查询的服务器限制)。然后,您需要通知主线程(或其他内容),以便它可以......做某事。

您的计划流程仍不明确。

根据您希望主线程执行的操作(以及您希望它执行此操作的信息),您有许多选项。你可以:

  • 创建另一个BlockingCollection个结果。当使用者完成请求时,它会向该集合添加一个对象。主线程轮询该集合以获取请求完成的通知。
  • 以上的变化是使用管道。一个线程将请求排队。一个线程使请求出列,发出Web请求,然后将结果放入另一个队列。第三个线程处理第二个队列。
  • 为每个ManualResetEventSlim对象添加一个事件(例如Request)。当消费者完成请求时,消费者会对该事件进行Set调用。主线程要么等待该事件,要么定期轮询它。
  • 让使用者执行回调函数(在编译时定义,或者在您添加到队列的Request对象中传递)。该回调函数可以通知主线程,记录结果或任何你喜欢的内容。

同样,如果没有关于您的应用程序的更多信息以及您尝试解决的更高级别问题,则很难提出更具体的建议。