【发布时间】:2016-01-05 14:56:37
【问题描述】:
我正在修改并行 foreach 中的元素列表,例如:
var items = ...; // array to process
for(;;){
Parallel.ForEach(items, po, (it) =>
{
it.Date = DateTime.Now; // Modify it with some logic.
}
}
我的案例不涉及任何竞速条件,并且这个类似的问题与我的案例无关(因为我对线程安全不感兴趣):
Parallel.ForEach on List<Object> Thread Safety
上述代码中的Date 是DateTime? 类型,最初是null。我从来没有在我的代码中把它变成null,我只把它设置为DateTime.Now。
问题是Parallel.ForEach 似乎提供items 的副本而不是真实实例,因此无法更新它们。我理解这一点,因为对于之前设置的项目,我得到了 null 的 Date 值。
这是预期的行为吗?尽管在将数据提供给线程之前复制数据听起来有点合乎逻辑,但我找不到任何文档。
我问,因为在上面发布的问题链接中,没有人说任何关于这个(更新并行 foreach 中的对象)是不可能/可靠的。
是否有任何好看的代码作为解决此问题的方法(以便我可以在循环数组时更新项目)?
更新:
在我的情况下,T 是这样的:
public class GroupSettings
{
public GroupSettings(int groupId, string email)
{
GroupId = groupId;
Email = email;
}
public int GroupId { get; protected set; }
public string Email { get; protected set; }
public DateTime? Date { get; set; }
}
我什至尝试将 Date 放在内部类中(以防万一副本中的对象引用相同),但行为没有改变。
【问题讨论】:
-
在这种情况下,
T是什么?听起来它可能是一个可变结构...如果不是,请发布一个简短但完整的示例来说明问题。 -
你的
items是什么类型的?它是值类型还是引用类型?如果它是引用类型(类)而不是值类型(结构),您的代码应该可以工作。 -
我已经更新了上面关于
T类型的问题。 :) -
为什么你的
Parallel.ForEach在一个无限循环中(for(;;))? -
您能展示一下您最初是如何填充
items的吗?它是由 Linq 查询创建的吗?如果是问题可能是惰性评估,因此每次迭代items时,都会根据查询重新评估值。
标签: c# .net multithreading parallel-processing