VivaLaPanda
VivaLaPanda

Reputation: 838

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

Upvotes: 1

Views: 1243

Answers (1)

VivaLaPanda
VivaLaPanda

Reputation: 838

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.

Upvotes: 2

Related Questions