简体   繁体   中英

Modifying properties in a C# list of objects in parallel

I have a list containing objects and I wish to run operations against each list item in parallel. One of those operations involves modifying a property of the object. I thought that shouldn't cause an issue thread-safety wise, but my unit test is failing randomly, so I'm worried there is a race condition.

The exact failure case is that the test will fail saying that the list is empty, but only if I run my my test regularly, if I run in debug mode the problem disappears. None of my code should be removing/adding elements, the list is generated at the start and then never directly modified, only the elements themselves are modified.

Is modifying properties on classes in a C# list threadsafe?

Here is the code in question:

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

Here is a more minimal example:

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

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

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

Alright, so the issue causing my problem wasn't a race case in the ForEach, but instead the combination of a timing issue and a singleton being shared in the test environment.

However, my original question was simply whether it was safe to use a C# list across threads assuming that the operations carried out with each list element were themselves threadsafe. In other words, is using Parallel.ForEach on a List just as thread safe/unsafe as doing a similar operation on an array. From the comments of users here, it appears the answer is yes .

Namely, that so far as thread safety goes a List can be considered equivalent to an array assuming the user isn't adding or removing elements from the list, sorting the list, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM