异步启动只有一个任务来处理静态队列,当它完成时停止

问题描述:

基本上我有一个我想要处理的对象的静态自定义队列。从多个线程中,我需要启动一个单独的任务来处理排队的对象,当所有项目出列时停止任务。异步启动只有一个任务来处理静态队列,当它完成时停止

一些伪代码:

static CustomQueue _customqueue; 
static Task _processQueuedItems; 

public static void EnqueueSomething(object something) { 
    _customqueue.Enqueue(something); 
    StartProcessingQueue(); 
} 

static void StartProcessingQueue() { 
    if(_processQueuedItems != null) { 
     _processQueuedItems = new Task(() => { 
     while(_customqueue.Any()) { 
      var stuffToDequeue = _customqueue.Dequeue(); 
      /* do stuff */ 
     } 
     }); 
    _processQueuedItems.Start(); 
    } 
    if(_processQueuedItems.Status != TaskStatus.Running) { 
     _processQueuedItems.Start(); 
    } 
} 

如果它的确与众不同我的自定义队列,直到他们达到一定的年龄,基本上保持项的队列,然后让他们离队。每次接触一件物品时,它的计时器会重新开始。我知道这件作品很好。

我正在努力的部分是并行性。 (显然,我不知道我在这里做什么)。 我想要的是让一个线程处理队列直到完成,然后离开。如果另一个调用进来,它不会启动一个新的线程,除非必须。

我希望能解释我的问题没关系。

您可能要考虑在这里使用BlockingCollection<T>。你可以让你的自定义队列实现IProducerConsumerCollection,在这种情况下BC可以直接使用它。

然后,您只需启动一个长时间运行的任务即可拨打blockingCollection.GetConsumingEnumerable()并在foreach中处理这些项目。任务将在收集为空时自动阻塞,并在新项目为Enqueued时重新启动。

+0

谢谢。我甚至不知道存在。出于好奇,你是怎么知道那里的?我想,我可能只需要阅读更多“X.0中的新功能”文章。 – 2012-04-09 23:48:46

+1

@blesh System.Collections.Concurrent有许多值得研究的好东西......这是记录http://msdn.microsoft.com/en-us/library/dd460718.aspx对于即将到来的,请参阅:http:/ /blogs.msdn.com/b/pfxteam/archive/2011/09/17/10212961.aspx – 2012-04-10 00:10:11