我正在创建一个webservice+servicebus项目,用户可以做一些像
public void ExecuteLongProcess(DateTime fromDate,string aggregateId){}
此方法立即返回但通过总线发送操作请求。
我的问题开始于当多个用户在同一个aggregateId上请求长进程时,而另一个已经在运行。
我正在考虑的解决方案是一个连续运行的任务,并在Queue<LongProcessTask>
中查找必须执行的操作,因此我一次只运行一个进程,或者如果不同的aggregateId,未来的实现将是多个进程。
这样我就不会在同一个聚合上重叠长时间运行的进程。
其他想法?
我创建了一个TaskRunner,它实例化了一些连续运行的任务(数量取决于处理器内核),这些任务在并发队列中查找并运行每个操作。TaskRunner从Windsor获得每个操作类型的处理程序,以便将每个操作的处理放在一个类中。
在您的回答中,您说多个线程将从并发队列中获取任务。在这种情况下,具有相同aggregateId的两个任务有可能同时运行。我不知道这对您来说是否有问题,如果有,那么您必须为每个aggregateId使用不同的队列。
如果任务顺序不是问题,那么我建议使用BlockingCollection。因为有一个问题:如果并发队列中没有任务,您打算如何处理多个消费者线程?
while(some_condition_to_keep_thread_alive)
{
if(!queue.TryDequeue(...))
continue;
else
{
//do the job
}
}
如果queue
为空,此代码将使您的内核发疯。你需要一个阻断机制。BlockingCollection会为你做这些。
你坚持使用ConcurrentQueue吗?SemaphoreSlim是你的朋友