排队嵌套线程

时间:2015-01-04 16:40:08

标签: c# .net multithreading

在我的计划中,产品(或成分)需要更新自己的父母价格,父母必须为父母做同样的事情。

我写过这样的方法:

public static Price CalculatePrice(this IProduct pro)
{
    /// calculation stuff
}

private static SystemContext innerContext;

/// <summary>
/// In the main controller this method called for updates
/// </summary>
/// <param name="pro"></param>
/// <param name="sc"></param>
public static void UpdatePrice(this IProduct pro, ref SystemContext sc)
{
    if (sc.Relations.Where(t => t.SubProduct.ID == pro.ID).Any())
    {

        // If this returns any, this means there are some products using this product as their sub-product.
        var list = sc.Relations.Where(t => t.SubProduct.ID == pro.ID).ToList();

            ConcurrentQueue<Relation> quee = new ConcurrentQueue<Relation>(list);

            innerContext = new SystemContext();

            Task task = new Task(() => UpdatePrice(ref quee));
            task.Start();
    }
}


private static void UpdatePrice(ref ConcurrentQueue<Relation> queue)
{
    Relation val;

    while (queue.TryDequeue(out val))
    {
        val.Product.Price = val.Product.CalculatePrice();

        var list = innerContext.Relations.Where(t => t.SubProduct.ID == val.Product.ID);

        if (list.Any())
        {
            ConcurrentQueue<Relation> quee = new ConcurrentQueue<Relation>(list);
            Task task = new Task(() => UpdatePrice(ref quee));
            task.Start();

        }
    }
}

虽然第一级父产品得到更新,但第二级却没有。

有没有更好的逻辑呢?

顺便说一句,任何最低级别的产品都有大约1000个父母(递归)。这意味着耗时(因为价格的计算)。因此,如果你考虑时间也提出建议,这将是完美的......

修改

我正在做一些测试。我认为,一些最低级别的产品有4000个父母。

1 个答案:

答案 0 :(得分:2)

我认为解决方案可能是迭代地而不是递归地处理数据。您可以通过将您感兴趣的所有产品添加到列表中并在处理其中的产品时继续添加到该列表中来实现。

这样的事情:

public static void UpdatePrice(this IProduct pro, ref SystemContext sc)
{
    var relations = sc.Relations.Where(t => t.SubProduct.ID == pro.ID).ToList();

    for (int i = 0; i < relations.Count; i++)
    {
        relations[i].Product.Price = relations[i].Product.CalculatePrice();
        relations.AddRange(sc.Relations.Where(t => t.SubProduct.ID == relations[i].Product.ID)); 
    }    
}