我想并行加载包含任务的列表,然后并行执行这些任务。 这些任务采用一个方法作为操作,但我需要该方法来处理每个任务的不同对象。但我无法传入参数。
所以我正在考虑这样的解决方案:
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。
可以这样做吗,还是我应该采取不同的做法? 我在这里并行完成工作吗?
最佳答案
您使用 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) });
}
关于c# - Parallel.For w 创建不同任务的 Action,c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22988630/