Correct way to block DataTable in C # for multithreading?

Is this the correct way to lock and modify a DataTable that is used by multiple threads? If not, what would be the right way to do this?

 private void DoGeocodeLookup(object info) { ParameterRow data = (ParameterRow)info; DataRow dr = data.Dr; int localIndex = data.Index; ManualResetEvent doneEvent = data.m_doneEvent; Geocode_Google.GeoCode gc = new GeoCode(); gc.Addr_In = m_dtAddress.Rows[localIndex]["AddressStd_tx"].ToString(); gc.GeoCodeOne(); if (gc.Status == "OK") { //write back to temporary datatable lock( m_TempTable.Rows.SyncRoot ) { m_TempTable.Rows[localIndex]["GL_Address"] = gc.Thoroughfare_tx; } } doneEvent.Set(); } 

My structure:

 struct ParameterRow { private DataRow m_row; private int m_index; public DataRow Dr { get { return m_row; } set { m_row = value; } } public int Index { get { return m_index; } set { m_index = value; } } public ManualResetEvent m_doneEvent; public ParameterRow( DataRow row, int index, ManualResetEvent doneEvent) { m_row = row; m_index = index; m_doneEvent = doneEvent; } } 

Snippet where I start all threads:

 //make temporary table m_TempTable = new DataTable(); m_TempTable = m_dtAddress.Copy(); for (int index = 0; index < m_geocodes; index++) { doneEvents[index] = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(DoGeocodeLookup, new ParameterRow( m_dtAddress.Rows[index], index, doneEvents[index])); } WaitHandle.WaitAll(doneEvents); 
+4
source share
2 answers

In your example, no DataTable lock is required. Inside DoGeocodeLookup you only format the DataTable read. The only access you perform in the table is to search for the row that is considered read. The DataTable class is marked as safe for multithreaded read operations. If you are doing something like adding DoGeocodeLookup to DoGeocodeLookup , you will need a lock.

The only thing you change is the data in one DataRow specified by localIndex . Since every DoGeocodeLookup call uses a differnet line - one row in your table will be updated with only one thread, so you have no synchronization problem. Thus, it also does not require locking.

+6
source

This thread is very informative and can help with your question. The general consensus is to use Interlock.Increment (object to update). Locking is slow, and you should remember everything and all places where you can lock the object that you are updating. And volatile does not necessarily mean that CPU A will see that CPU B immediately changed.

0
source

All Articles