6

NullReferenceException関連するすべてのオブジェクトが有効な行にスローされています。StackTrace行番号が 432 であることを示しています。

コードは

ここに画像の説明を入力

ここではFlagstempFlags両方ともデータテーブルです。両方のデータテーブルの列のデータ型はプリミティブ (decimal、datetime、short) です。アプリケーションはマルチスレッド アプリケーションであり、コード スニペットはスレッド関数に属します。Flagsインスタンスレベルで宣言されます。つまりtempFlags、スレッド関数内で宣言されている間、すべてのスレッドで共有されます。

ここで、この特定のインスタンスでは、Flags1946 レコードtempFlagsが含まれ、1 が含まれています。

編集#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

432行目をロック内に配置した後、例外がなくなったため、Mergeステートメントはスレッドセーフではないようです。

4

3 に答える 3

4

フレームワーク内から取得してマルチスレッド化するときはいつでもNullReferenceException、ほぼ確実に、あるべき場所にロックを適用していないスレッドセーフの問題です。

于 2013-01-02T05:40:43.440 に答える
2

新しい行を挿入するときに発生しているように見えるのでSystem.Data.DataTable.InsertRow(DataRow row, Int64 proposedID)、フィールドをnullにできないという制約があると思います。そして、ソース テーブルから null を挿入しようとしています。

または、計算列があり、入力列の 1 つが null です。

于 2013-01-02T05:32:15.923 に答える
1

このコードに固有のこの例外 (IMO) の説明。

スレッド A が Merge を実行していて、Merge に格納されているデータテーブルを として渡しているとしましょうDt1referenceToDatatable

スレッド B が入ってきて、 asに格納されDt2ているものに渡します (非プリミティブ オブジェクトは参照によって渡され、Merge はスレッド セーフではなく、ロックがないため、参照は同じです)、したがって、によって上書きされます。MergeMergereferenceToDatatableDt1Dt2

Dt2は同じ構造であり、そうではないため、これまでのところ例外はありませんnull

ここで、スレッド B が中断され、スレッド A が入り、完了しMergeて終了するため、Dt1どちらも無効になりreferenceToDatatableます。

スレッド B が入ってきて、見つかったreferenceToDatatable = null->例外

于 2013-01-08T06:15:27.637 に答える