Parallel.For w创建不同任务的Action,c#

时间:2014-04-10 12:51:52

标签: c# multithreading azure parallel-processing

我想并行加载包含任务的列表,然后并行执行这些任务。 任务将方法作为操作,但我需要该方法来处理每个任务的不同对象。但我无法传递参数。

所以我正在考虑这样的解决方案:

public static Order order = new Order();
public static Queue<SubOrder> subsQ = order.SubOrders;

public void Work()
{
    Task[] taskList = TaskMaker(order.SubOrders.Count);
    Task.WaitAll(taskList);
}

public Task[] TaskMaker(int orderCount)
{
    Task[] taskList = new Task[order.SubOrders.Count];
    Parallel.For(0, taskList.Length, i => taskList[i] = new Task(ExecuteSubOrder) );
    return taskList;
}

public void ExecuteSubOrder()
{
    SubOrder subO = subsQ.Dequeue();
    // ... execute suborder, some webrequest etc.
    ordersCompletedTable.Execute(TableOperation.Insert(new SubOrder(subO.SubOrderId, subO.Status)),
        new TableRequestOptions() { RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3) });
}

public class Order
{
    public Queue<SubOrder> SubOrders { get; set; }
}

该方法执行订单,并在每个完成的订单上记录在azure表中。 该方法为使用Parallel.For放入Task []的每个任务的新顺序排队,这样我就可以使用该任务数组调用Parallel.WaitAll。

可以这样做,还是应该以不同的方式做? 我在这里并行完成工作吗?

1 个答案:

答案 0 :(得分:2)

您正在使用Parallel.For为每个子订单创建新任务,但随后从任务中的共享数据结构中检索子订单。这不是理想的路线,因为当每个任务开始执行时,它会导致竞争危险(如果不同步)或瓶颈(如果同步)。

相反,更改ExecuteSubOrder方法的定义以接受其子顺序作为参数,然后使用Parallel.ForEach将子顺序并行化到任务上。 Parallel.ForEach还会在返回之前等待所有子订单完成。

public void Work()
{
    Parallel.ForEach(order.SubOrders, ExecuteSubOrder);
}

public void ExecuteSubOrder(SubOrder subO)
{
    // ... execute suborder, some webrequest etc.
    ordersCompletedTable.Execute(TableOperation.Insert(new SubOrder(subO.SubOrderId, subO.Status)),
        new TableRequestOptions() { RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3) });
}