2

So I am attempting to process records from a datatable one row at a time. I am new to multi-threaded environments and I was asked to use Parallel.Foreach Loop. I wanted to know how local variables are treated in a Parallel execution mode. Following is my code.

Parallel.ForEach(dtReportData.Tables[0].AsEnumerable(), drow =>
{
string strType = drow["type"];
//Based on this type, I am executing logic from a switch case.

});

Now. I want to know if I can declare and assign value to the variable inside the loop. For an instance, let's assume that there are 2 threads running in parallel.

Thread 1 fetched a record and let's say that the value that was fetched was "Type1" and stored into strType. Now, I want my code to perform the logic for type "Type1" (Let's assume that we have written a switch case for it)

However, let's assume that before Thread 1 starts executing the logic, thread 2 comes into play. Thread 2 assigns the value "Type2" to the strType.

Now, when Thread 1 goes to my Switch block, what value will it hold? Will it be "Type1" or "Type2".

Note that I am not globally declaring the value of the String variable outside the Foreach loop, it's inside the loop and I believe that a new instance is created everytime.

1 Answers1

0

The variable strType is local to this lambda invocation, and no other thread is able to see it or modify it. Its value is stored in the stack of the current thread. Each thread has its own stack, with a size of 1 MB.

As a side note, be aware that the ADO.NET classes in general, and the DataTable class in particular, are not thread-safe. If you try to mutate them from multiple threads in parallel, their internal state may become corrupted, and their behavior will become undefined.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • Hi Theodor, Thanks for your response. So I am assuming that I will be able to use the variable, without having it's value overwritten by a new thread. Also, I am aware that I won't be able to perform write operations on DataRow class. I have used the 'lock' block in case I have to write something (which kills the purpose of using a parallel foreach, but then 'The Boss is always right') – Ashish Samant Apr 14 '20 at 07:58
  • Hi Ashish. Yeap, you can be confident that the local variable is not going to be shared with other threads. Regarding the thread-safety of the `DataTable`, if you lock for writing then must lock for reading too. Otherwise you may get exceptions or incorrect results. – Theodor Zoulias Apr 14 '20 at 08:13
  • Hi Theo, Thanks for your response. The reason that I am not locking while reading is because I am not modifying the column values from which I am reading. – Ashish Samant Apr 20 '20 at 09:04
  • If you know for sure that no other thread is writing while the current thread is reading, then by omitting the lock you are still risking that the current thread may not see the most recent changes made to the `DataTable`. The C# language itself offers no guarantees in that case. You can read [here](https://learn.microsoft.com/en-us/archive/msdn-magazine/2012/december/csharp-the-csharp-memory-model-in-theory-and-practice) the visibility guarantees (or the lack of) offered by the language. My advice is: always lock when accessing shared state (when both writing **and** reading). – Theodor Zoulias Apr 20 '20 at 11:34