0

Suppose I have this scenario:

class Container {
    public string Item1 { get; set; }
    public int Item2 { get; set; }
}

// And I have an array like this:

List<Task> tasks = new List<Task>();
Container[] arr = new Container[10];
for (int i = 0; i < arr.Length; ++i) {
    arr[i] = new Container();
    
    tasks.Add(Task.Run(() => FillContainer(arr[i])));
}

Task.WaitAll(tasks.ToArray());

// Do something with arr like writing to json file

FillContainer mutates the container that is passed in (changes the Item1 and Item2 properties).

Would this be safe (assuming only that single block of code is being executed)?

I'm assuming it would be because each Container object has it's own chunk of memory which is being mutated by a single thread.

  • 1
    "safe" is a property of an entire program. Without knowing what else is accessing that data and how, as well as what the program is supposed to do, we can't know if they do so in a way that will produce the intended behavior. – Servy Jul 02 '21 at 22:12
  • @Servy For this example, assume that nothing else is happening other than the block of code – NewUwpPerson Jul 02 '21 at 22:12
  • If you have no desired result or behavior, then just delete the code and do nothing. If you want to actually *do* something you can then consider whether or not your code successfully accomplishes that goal, which first requires *specifying* that goal. – Servy Jul 02 '21 at 22:15
  • 4
    Your program currently suffers from this problem: [Captured variable in a loop in C#](https://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp). In short all 10 tasks are going to mutate the 10nth `Container` instance, which is unlikely to be your intention. – Theodor Zoulias Jul 02 '21 at 22:22
  • 1
    If we "assume that nothing else is happening other than the block of code" then who cares what the result is? So we need to assume you want the result to be correct because you use it afterwards. Yes it would not have unsafe threading issues. Other points: loop variable capture as mentioned. `Task.Run` does not guarantee a different thread anyway. You shouldn't slap `Task.Run` in just to use `await`, instead ensure `FillContainer` is async. There is no point parallelizing unless CPU bound, and only up to the number of processor cores. `Task.WaitAll` is a bad idea, better `await Task.WhenAll`. – Charlieface Jul 03 '21 at 22:49
  • 1
    It seems to me that, in this case, `Parallel.ForEach` would be a better option. – Enigmativity Jul 04 '21 at 02:49

0 Answers0