views:

31

answers:

1

I'm helping spruce up an application, and it's full of concurrency issues. I'm attempting to work through them, and came across a section that's using DataTables.

The datatable itself is static, shared across many threads.

I know that using dt.Select("...") itself needs a lock statement, or you'll have issues when adding/removing rows to the data table. However, when that call returns, you have an array of DataRow objects.

I'd obviously lock those rows if I was to update them, but if I'm just reading them, do they need locking?

Basically, given that elsewhere we're adding new rows and potentially updating existing rows, which of these is correct:

lock (dtLock)
{
    DataRow[] rows = dt.Select("...");
}
foreach(DataRow dr in rows)
{
    // read statements only
}

or

lock (dtLock)
{
    DataRow[] rows = dt.Select("...");

    foreach(DataRow dr in rows)
    {
        // read statements only
    }
}
A: 

Since you stated that you will be updating existing rows then you have no other choice but to lock access to the rows you extract from Select. You cannot (or at least should not) access the rows, even just reads, if there is a possibility that they can be modified by another thread. Furthermore it is possible (and I have seen ancedotal evidence myself) that accessing an individual row can touch the underlying DataTable's internal structure so even if you were just adding new rows there still might be a problem.

Brian Gideon
Ugh. I figured as much, and thanks for the bit about accessing the rows; I was wondering about that too, since I think DataTables share PKs across rows, etc. Microsoft's site says DataTables are safe for read access, which really means absolutely nothing if the rows themselves aren't.
jvenema
@jvenema: Yeah, they are definitely safe for multiple readers, but once you throw a writer in the mix it changes everything.
Brian Gideon
Yeah, I don't really care if the records are out of date here and there, but (for example) select throws an error if you call .Add() while it's working....and that causes problems :)
jvenema