The title of this post might seem really silly considering MSDN specifically says they aren’t thread safe, but there’s more to it than that. It says DataTables are not thread safe for WRITE operations which is a major ‘”Duh” statement, but in reality they are not safe for some read operations. I’ve been having some strange issues with DataRows in parallel loops so I started to investigate.
I saw a post stating that DataTable.Select() is actually a write operation so it isn’t thread safe and requires a lock. I don’t see anything on MSDN about this. So I got to thinking and that’s when I opened up dotPeek. What did I find?
DataTable.NewRow() is not thread safe! The point of this method is to create a new row with the same schema as the table. According to MSDN you have to then add that row to the table’s DataRowCollection, it is not automatically added to the row collection when calling NewRow(). This, for the most part, is a read operation which would be thread safe. BUT, at one point in the internals, a call to NewRow(int) is made which creates the new record object, then sets that record to a class scoped field before passing it along to a DataRowBuilder. This is where it is no longer thread safe.
I was seeing so many problems because I was using NewRow() in a parallel loop and data was being corrupted at the end. This was why. To combat this, I generated a cache of new rows before the parallel loop, in a ConcurrentBag<DataRow> and then use a TryTake() inside of the loop. No more problems.