我有一个数据库同步任务需要一些时间来处理,因为在120k叶子记录的区域中,但它们是远程的并且访问相对较慢。
目前,我的应用程序做了一个相当天真的过程
步骤1在数据完成之前返回数据,步骤4不涉及同一组中不同联系人之间的比较。
我希望做的是使用某种队列构造并在步骤1中开始填充它,然后立即转到步骤2并使用多个线程开始处理项目。
然后该过程变为:
我是否正确地假设我可以创建一个新的ConcurrentQueue,开始填充它,然后循环它,因为我可能是一个单线程的简单集合?
(我没有进行任何错误检查或实际线程,以保持示例简单)
class Program
{
static void Main(string[] args)
{
Processor p = new Processor();
p.Process();
}
}
class Processor
{
bool FetchComplete = false;
ConcurrentQueue<Contact> q = new ConcurrentQueue<Contact>();
public void Process()
{
this.PopulateQueue(); // this will be fired off using QueueUserWorkItem for example
while (FetchComplete == false)
{
if (q.Count > 0)
{
Contact contact;
q.TryDequeue(out contact);
ProcessContact(contact); // this will also be in QueueUserWorkItem
}
}
}
// a long running process that fills the queue with Contacts
private void PopulateQueue()
{
this.FetchComplete = false;
// foreach contact in database
Contact contact = new Contact(); // contact will come from DB
this.q.Enqueue(contact);
// end foreach
this.FetchComplete = true;
}
private void ProcessContact(Contact contact)
{
// do magic with contact
}
}
答案 0 :(得分:2)
您最好使用BlockingCollection
代替ConcurrentQueue
。原因是前者将阻塞调用Take
的线程,直到项目出现在队列中。当处理Contract
实例的线程在获取所有线程之前清除队列时,这将非常有用。
总的来说,你的策略非常可靠。我用它所有的时间。它通常被称为生产者 - 消费者模式。当处理涉及超过2个阶段时,它被称为管道模式。在这种情况下,您将拥有2个或更多队列,而不是典型的队列。您可以想象每个阶段通过另一个队列将工作项转发到下一个阶段的场景。