6

NullReferenceException被抛出在所有涉及的对象都有效的线上。StackTrace显示第 # 行是 432。

代码是

在此处输入图像描述

在这里,Flags两者tempFlags都是数据表。两个数据表的列的数据类型都是原始的(十进制、日期时间、短)。该应用程序是一个多线程应用程序,代码片段属于线程函数。Flags在实例级别贴花,即tempFlags在线程函数内部声明时共享给所有线程。

在这个特定的时间实例中,Flags包含 1946 条记录并tempFlags包含 1。那么,为什么会出现 NullReferenceException 呢?

编辑#1

ex.InnerException
null
ex.StackTrace
at System.Data.DataTable.RecordStateChanged(Int32 record1, DataViewRowState oldState1, DataViewRowState newState1, Int32 record2, DataViewRowState oldState2, DataViewRowState newState2)
at System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID)
at System.Data.DataTable.MergeRow(DataRow row, DataRow targetRow, Boolean preserveChanges, Index idxSearch)
at System.Data.Merger.MergeTable(DataTable src, DataTable dst)
at System.Data.Merger.MergeTableData(DataTable src)
at System.Data.Merger.MergeTable(DataTable src)
at System.Data.DataTable.Merge(DataTable table, Boolean preserveChanges, MissingSchemaAction missingSchemaAction)
at System.Data.DataTable.Merge(DataTable table)
at [...].cs:line 432"
ex.Data
    {System.Collections.ListDictionaryInternal}
        [System.Collections.ListDictionaryInternal]: {System.Collections.ListDictionaryInternal}
        IsFixedSize: false
        IsReadOnly: false
        Keys: {System.Collections.ListDictionaryInternal.NodeKeyValueCollection}
        Values: {System.Collections.ListDictionaryInternal.NodeKeyValueCollection}
ex.Message
"Object reference not set to an instance of an object."
ex.Source
"System.Data"

编辑#2

看起来 Merge 语句不是线程安全的,因为在将第 432 行放入锁后,异常消失了,SO FAR。

4

3 回答 3

4

每当您NullReferenceException从框架中获取并且您正在使用多线程时,几乎可以肯定这是一个线程安全问题,您没有在应该在的地方应用锁。

于 2013-01-02T05:40:43.440 回答
2

由于它似乎在插入新行时发生,System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID)我猜有一个约束说字段不能为空。您正在尝试从源表中插入一个空值。

或者,有一个计算列并且其中一个输入列为空。

于 2013-01-02T05:32:15.923 回答
1

特定于这段代码的此异常 (IMO) 的说明。

假设线程 A 正在执行 Merge 并将Dt1存储在 Merge 中的数据表传递为referenceToDatatable,同时

线程 B 进来并传递Dt2Merge它,存储在Mergeas 中referenceToDatatable(引用是相同的,因为非原始对象是通过引用传递的,Merge 不是线程安全的并且没有锁),因此Dt1被 覆盖Dt2

到目前为止没有例外,因为Dt2它具有相同的结构,但它不是null

现在线程 B 被挂起,线程 A 进入,完成Merge并退出,因此无效Dt1,也无效referenceToDatatable

现在线程 B 进来发现referenceToDatatable = null->异常

于 2013-01-08T06:15:27.637 回答