Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
并行修改C#对象列表中的属性_C#_Parallel Processing_Task Parallel Library_Parallel.foreach - Fatal编程技术网

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

并行修改C#对象列表中的属性,c#,parallel-processing,task-parallel-library,parallel.foreach,C#,Parallel Processing,Task Parallel Library,Parallel.foreach,我有一个包含对象的列表,我希望对每个列表项并行运行操作。其中一个操作涉及修改对象的属性。我认为这不会导致线程安全方面的问题,但我的单元测试随机失败,所以我担心存在竞争条件 确切的失败案例是,测试将失败,说明列表为空,但只有当我定期运行测试时,如果我在调试模式下运行,问题才会消失。我的任何代码都不应该删除/添加元素,列表在开始时生成,然后从不直接修改,只修改元素本身 修改C#列表中类的属性是否线程安全 以下是相关代码: List<ExampleObject> localApplicat

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

确切的失败案例是,测试将失败,说明列表为空,但只有当我定期运行测试时,如果我在调试模式下运行,问题才会消失。我的任何代码都不应该删除/添加元素,列表在开始时生成,然后从不直接修改,只修改元素本身

修改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);
    }
});

好的,导致我的问题的不是ForEach中的种族问题,而是时间问题和测试环境中共享的单例的组合

然而,我最初的问题只是假设每个list元素执行的操作本身是线程安全的,那么跨线程使用C#list是否安全。换句话说,在列表上使用Parallel.ForEach与在数组上执行类似操作一样是线程安全/不安全的。从这里的用户评论来看,答案似乎是


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

如果您可以共享一个列表,那就太棒了。我在这里没有看到共享资源,您正在修改分配给特定线程的对象,这应该可以工作,问题在于,只有当存在共享资源时,更新后的示例才不会出现问题,因为属性永远不会交互,并且应该通过测试。当多个线程尝试修改同一资源时,线程安全性将发挥作用。在您的例子中,您迭代列表,并为每个线程提供自己的对象,而不是修改列表本身。一切都很好。您的问题没有说明由于列表变空而导致的错误。这似乎是需要包含的相关信息。这就是为什么下次发生类似情况时,您必须提供。大多数程序员在遇到问题时都倾向于仓促进入眨眼模式——假设他们了解问题所在。A迫使你花时间缩小原因,而不是过早地做出假设。是的,我想我还不清楚。我试图弄清楚,我所关心的只是在一般情况下对列表中的项目进行变异是否是线程安全的。我可以自己解决其他问题。我在别处找不到关于线程安全问题的明确答案。文档通常非常清楚线程安全-。
var object = new { 
    prop = "foo"
};
var list = new[] { object }.ToList();

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

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