add rows to a datatable with parallel.for
I have this sub :
Private Sub error_out(ByVal line As Integer, ByVal err_col As Integer, ByVal err_msg As开发者_StackOverflow中文版 String)
Dim ln = t_erori.Rows.Add
ln.Item(0) = line
ln.Item(err_col) = err_msg
ln.Item(3) = err_col
End Sub
This is being called by several functions running in a parallel.for loop.
The problem is that sometimes (totally random) i get an error:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
on the Dim ln = t_erori.Rows.Add
line.
I suspect this is because it's trying to add the same row twice. How can i make this work ? Or what else method could I use to do this ?
I need this datatable because my app is writing some results in there, but any other method to store the results that works with parallel.for would be ok.
This is a disease of new parallel extensions. You can easily write unsafe code. MSDN for DataTable says:
Thread Safety
This type is safe for multithreaded read operations. You must synchronize any write operations.
You are performing not thread safe operation in several threads. You have to either use lock
or SpinLock (preferred) or ReaderWriterLockSlim.
The naive approach to fixing this is to wrap everything in a SyncLock
block.
Private Sub error_out(ByVal line As Integer, ByVal err_col As Integer, ByVal err_msg As String)
SyncLock t_erori
Dim ln = t_erori.Rows.Add
ln.Item(0) = line
ln.Item(err_col) = err_msg
ln.Item(3) = err_col
End SyncLock
End Sub
The problem here is that you have effectively serialized the execution of error_out
since all threads have to contend for the same lock. The end result is that this could end up running slower than the equivalent non-parallelized version.
The simplest way to take advantage of threads here is to delegate the entire operation of adding the rows to the DataTable
to a worker thread and let the main thread continue on with what it was doing and then join the worker thread to the main thread via Thread.Join
when it is time for the main thread to request completion of the operation.
精彩评论