我有一项任务,我觉得很有挑战性,不知道如何开始。
问题是:
说:"我得到了一排随机的产品(包括a、B和C型)。"
p[A]、p[A],p[B]、p[C],p[C]、p[A]、p[B],p[B]。。。。
我将同时将这些产品发送到ProcessProduct(),但两个相同类型的产品不能一起处理。
以下是场景:
第一个p[A]将被处理,第二个p[A]将不得不等待第一个,第三个p[B]和第四个p[C]将立即被处理,而第五个p[C将不得不等待前一个。。。。
希望我的描述不要太混乱。如果有人能给我一些建议,我将不胜感激。非常感谢。
实现这一点的一种方法是将项目分组为三个不同的queus,每个类型一个队列。这会增加一些开销,但会让它变得容易得多。
这里有一些伪代码:
queueForTypeA=new queue()
queueForTypeB=new queue()
queueForTypeC=new queue()
foreach product in products
if product is typeof A
addLastInQueue(queueForTypeA, product)
if product is typeof B
addLastInQueue(queueForTypeB, product)
if product is typeof C
addLastInQueue(queueForTypeC, product)
然后,您可以分别处理每个队列,而不必担心一次处理2个相同类型的队列。
然而,此解决方案的扩展性不太好,如果您添加另一种类型的产品,则需要更改代码,这并不是最佳的。
因此,另一种选择是列出您正在处理的类型,然后每当您希望处理新产品时,您都会重新访问队列中的第一个项目,如果产品类型在productTypesBeingProcessed
-列表中,则跳过行,选择下一个。
按类型对产品列表进行分组,然后并行处理每组。
已编辑
这是一个示例(如果产品列表是静态的):
sealed class Product
{
public string Type
{
get;
set;
}
}
sealed class ProductProcessor
{
public void StartProcessing(IEnumerable<Product> products)
{
foreach (var group in products.GroupBy(x => x.Type))
Task.Factory.StartNew(() => ProcessProducts(group));
}
private void ProcessProducts(IEnumerable<Product> products)
{
foreach (Product product in products)
ProcessProduct(product);
}
private void ProcessProduct(Product product)
{
}
}
这是要处理的动态产品队列的另一个示例(我没有运行代码,将其作为一种伪代码读取):
sealed class ProductProcessor
{
public void Process(Product product)
{
lock (_queues)
{
if (_queues.ContainsKey(product.Type))
_queues[product.Type].Enqueue(product);
else
{
ConcurrentQueue<Product> queue = new ConcurrentQueue<Product>();
queue.Enqueue(product);
_queues.Add(product.Type, queue);
WaitCallback action = delegate(object state)
{
Product productToProcess;
while (queue.TryDequeue(out productToProcess))
{
ProcessProduct(productToProcess);
}
lock (_queues) _queues.Remove(product.Type);
};
ThreadPool.QueueUserWorkItem(action);
}
}
}
private Dictionary<string, ConcurrentQueue<Product>> _queues
= new Dictionary<string, ConcurrentQueue<Product>>();
private void ProcessProduct(Product product)
{
}
}
附言:您可以使用ConcurrentDictionary来代替锁。
使用生产者-消费者队列的数组,按产品类型进行索引。每个队列中只挂起一个线程,因此对每个产品类型依次调用ProcessProduct()。
我们只需为每种类型使用一个队列。然后每个队列一次只能有一个作业。所以您可以在每个队列的线程上使用。
我甚至看不出这里有什么问题?你在要求什么?代码示例?功能?
因为你似乎拘泥于概念,但大部分似乎都在这里。关键是每个队列只影响一个线程(如果不需要直接使用线程,则影响作业)