我有一个简单的方法:
private IEnumerable<OrderResult> SubmitOrders(IEnumerable<OrderItem> items)
{
ConcurrentBag<OrderResult> results = new ConcurrentBag<OrderResult>();
Parallel.ForEach(items, item =>
{
OrderResult result = SubmitOrder(item);
results.Add(result);
});
return results;
}
要添加更多上下文,上面引用的SubmitOrder(item)方法会将'item'对象的“Sent”(DateTime?)属性更改为DateTime.Now,如果订单已成功提交。
在Parallel.ForEach循环中,在SubmitOrder(item)之后,我可以看到“已发送”属性已正确更新。
但是,如果我检查传入的“items”参数中的对象,则没有任何“已发送”属性已更新。就好像传递给Parallel.ForEach循环的项目不是原始“items”集合中的项目。
这是为什么?如果在循环中修改了传入集合中的对象,我希望更改能够反映在原始集合中的项目中,但它们似乎不是。
答案 0 :(得分:4)
items
的参数类型为IEnumerable<OrderItem>
。如果尚未枚举items
,并且枚举它们会创建新对象,那么这可能是原因,因为您在SubmitOrder()
中更新的对象与下次的对象不同枚举items
。这是一个完整的LINQPad C#程序,它演示了我的意思。
void Main()
{
IEnumerable<OrderItem> itemsAsIEnumerable =
Enumerable
.Range(1, 5)
.Select(i => new OrderItem() { ItemNumber = i });
SubmitOrders(itemsAsIEnumerable);
itemsAsIEnumerable.Dump();
/* Displays:
ItemNumber Sent
1 null
2 null
3 null
4 null
5 null
*/
IEnumerable<OrderItem> itemsAsList =
Enumerable
.Range(1, 5)
.Select(i => new OrderItem() { ItemNumber = i })
.ToList();
SubmitOrders(itemsAsList);
itemsAsList.Dump();
/* Displays:
ItemNumber Sent
1 2/5/2014 10:01:58 AM
2 2/5/2014 10:01:58 AM
3 2/5/2014 10:01:58 AM
4 2/5/2014 10:01:58 AM
5 2/5/2014 10:01:58 AM
*/
}
private IEnumerable<OrderResult> SubmitOrders(IEnumerable<OrderItem> items)
{
ConcurrentBag<OrderResult> results = new ConcurrentBag<OrderResult>();
Parallel.ForEach(items, item =>
{
OrderResult result = SubmitOrder(item);
results.Add(result);
});
return results;
}
private OrderResult SubmitOrder(OrderItem item)
{
item.Sent = DateTime.Now;
return new OrderResult();
}
public class OrderItem
{
public int ItemNumber { get; set; }
public DateTime? Sent { get; set; }
}
public class OrderResult
{
}