并行修改 C# 对象列表中的属性

Modifying properties in a C# list of objects in parallel

我有一个包含对象的列表,我希望对每个列表项并行进行 运行 操作。其中一个操作涉及修改对象的 属性。我认为这不应该导致线程安全问题,但我的单元测试随机失败,所以我担心存在竞争条件。

确切的失败案例是测试将失败,说列表为空,但前提是我 运行 定期进行我的测试,如果我 运行 在调试模式下,问题就会消失。 None 我的代码应该是 removing/adding 个元素,列表是在开始时生成的,然后从不直接修改,只修改元素本身。

修改 C# 列表中 类 的属性是否线程安全?

这里是有问题的代码:

List<ExampleObject> localApplications = MethodThatProducesTheList();

Parallel.ForEach(localApplications, localitem =>
{
    if (localitem.BuildLabel.Contains("_Release_"))
    {
        // Delete applications from the old system
        var appToDelete = Path.Combine(AppRootPath, localitem.Name, localitem.BuildLabel);
        DeleteDirectory(appToDelete);
    }
    else
    {
        var st = MethodThatGetsTheState(localitem.BuildLabel);

        localitem.State.Add(st);
    }
});

这是一个更简单的例子:

var object = new { 
    prop = "foo"
};
var list = new[] { object }.ToList();

Parallel.ForEach(list, listItem =>
{
    listItem.prop = "bar";
});

if (list[0].prop != "bar") {
    Assert.Fail()
}

好的,所以导致我的问题的问题不是 ForEach 中的竞争案例,而是计时问题和测试环境中共享的单例的组合。

但是,我最初的问题只是假设对每个列表元素执行的操作本身都是线程安全的,跨线程使用 C# 列表是否安全。换句话说,在 List 上使用 Parallel.ForEach 就像线程 safe/unsafe 在数组上执行类似操作一样。从此处用户的评论来看,答案似乎是

也就是说,就线程安全而言,假设用户没有在列表中添加或删除元素、对列表进行排序等,List 可以被认为等同于数组。