我得到了一项任务,我发现它非常具有挑战性,我不知道如何开始。
以下是问题:
我有一个随机产品队列(由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]将不得不等待前一个....
希望我的描述不会太混乱。 如果有人能给我一些建议,我将不胜感激。 谢谢。
答案 0 :(得分:1)
执行此操作的一种方法是将项目分为三个不同的队列,每个类型一个队列。这会增加一些开销,但会让它变得更容易。
这是一些伪代码:
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个相同类型的队列。
但是,此解决方案无法很好地扩展,如果您添加其他类型的产品,则需要更改代码,这不是最佳选择。
所以另一种选择是拥有一个您正在处理的类型列表,然后每次要处理新产品时,如果产品类型在{{1}中,您将重新访问队列中的第一个项目} -list,你跳过排队并接下一个。
答案 1 :(得分:1)
按类型对产品清单进行分组,然后并行处理每个组。
<强> EDITED 强>
这是示例(如果产品列表是静态的):
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)
{
}
}
P.S。您可以使用ConcurrentDictionary而不是锁。
答案 2 :(得分:0)
使用按产品类型索引的生产者 - 消费者队列数组。仅从每个队列挂起一个线程,因此为每个产品类型顺序调用ProcessProduct()。
答案 3 :(得分:0)
只需为每种类型使用一个队列。然后每个队列一次只能有一个作业。 所以你可以在队列中使用线程。
我甚至不能在这里看到问题?你在问什么?代码示例?功能 ?
因为你似乎被困在概念上,但大部分似乎都在这里。 关键是只影响每个队列的一个线程(如果你不需要直接使用线程,那么就是工作)