1

我有这个子:

Private Sub error_out(ByVal line As Integer, ByVal err_col As Integer, ByVal err_msg As String)

            Dim ln = t_erori.Rows.Add
            ln.Item(0) = line
            ln.Item(err_col) = err_msg
            ln.Item(3) = err_col
    End Sub

这是由运行在 parallel.for 循环中的几个函数调用的。

问题是有时(完全随机)我得到一个错误:

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

Dim ln = t_erori.Rows.Add线。

我怀疑这是因为它试图两次添加同一行。我怎样才能使这项工作?或者我还能用什么方法来做到这一点?

我需要这个数据表,因为我的应用程序正在其中写入一些结果,但是任何其他存储与 parallel.for 一起使用的结果的方法都可以。

4

2 回答 2

2

这是一种新的并行扩展的疾病。您可以轻松编写不安全的代码。数据表的 MSDN说:

线程安全

这种类型对于多线程读取操作是安全的。您必须同步任何写入操作。

您在多个线程中执行非线程安全操作。您必须使用SpinLocklock (首选)或ReaderWriterLockSlim。

于 2010-07-13T12:16:04.547 回答
1

解决此问题的天真的方法是将所有内容包装在一个SyncLock块中。

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 

这里的问题是您已经有效地序列化了的执行,error_out因为所有线程都必须争夺同一个锁。最终结果是,这最终可能会比等效的非并行版本运行得更慢。

在这里利用线程的最简单方法是将向工作线程添加行的整个操作委托给工作线程,让主线程继续它正在做的事情,然后通过何时DataTable将工作线程加入主线程Thread.Join是主线程请求完成操作的时间。

于 2010-07-15T03:41:27.397 回答