【发布时间】:2014-02-05 16:26:29
【问题描述】:
我有一个简单的方法:
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) 之后,我可以看到“Sent”属性已正确更新。
但是,如果我检查传入的“items”参数中的对象,则没有任何“Sent”属性被更新。就好像传递到 Parallel.ForEach 循环中的项目不是原始“项目”集合中的项目。
这是为什么?如果传入集合中的对象在循环中被修改,我希望这些更改会反映在原始集合中的项目中,但它们似乎没有。
【问题讨论】:
-
而且
OrderItem不是值类型,对吧? -
不,OrderItem 是一个类。但是在循环中分配的“Sent”属性是 Nullable
类型(结构),我想知道这是否是问题所在。 -
什么目标框架?
-
Visual Studio 2012 中的编译器发生了变化,改变了处理闭包的方式,从而复制了一些变量,而不仅仅是引用。但是,我看不出这会对您产生什么影响,因为没有任何其他代码(在 ForEach 之外)可以修改集合中的项目;所以即使有副本,也应该和原件一样。
-
如果这是一个克隆/深度复制的对象,对我来说是有意义的,但我不确定如何证明是这样。或者,甚至为什么会这样?
标签: .net parallel.foreach