2

ここには多くの同様の質問がありましたが、私の場合に何が起こっているのかを説明するものはありません。ここに行きます。

次の(簡略化された)コードがあります。

' row is a System.Data.DataRow
' _typeProperties is a Dictionary(Of String, PropertyInfo)

Dim data As New Dictionary(Of String, Object)
Dim elem As KeyValuePair(Of String, PropertyInfo)
Dim value As Object = Nothing
Try
    For Each elem In _typeProperties
        value = row.Item(elem.Key)
        data.Add(elem.Key, value)       ' NullReferenceException here
    Next
Catch ex As Exception When MyExceptionFilter(ex, data, elem, value)
End Try

指定された行で NullReferenceException が発生することがあります。この例外は非常にまれであり、自由に再現することはできません。ただし、アプリケーションを変更して顧客に送信すると、数日後には自然に再現されます。

コール スタックはあまり役に立ちません。

StackTrace: 
  XXX.RowToType(DataRow row) in C:\XXX.vb:line 645.

さらに、ご覧のとおり、Catch ブロックに例外フィルターを含めました。そこにミニダンプを書き込みます (例外のコール スタックはそのまま)。ミニダンプによって明らかになったコール スタックの関連部分を次に示します。

  ...
  App.exe!MyExceptionFilter( ex,  data,  elem,  value) Line 627
  App.exe!RowToType( row) Line 647 + 0x1f bytes
  [External Code]   
  App.exe!RowToType(System.Data.DataRow row) Line 645 + 0x112 bytes
  App.exe!SomeClass.get_Item(Integer index) Line 1141 + 0xe bytes   
  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes    
  user32.dll!_UserCallWinProcCheckWow@32()  + 0x693 bytes   
  ...

[External Code] ブロックのどこかで例外が発生します。次に、Catch ブロックのフィルターが実行されます (2 行目と 1 行目)。

例外の時点で、これらは関連する 3 つの変数の値です。

  data: Not Nothing; 
  elem: Not Nothing; 
  elem.Value: Not Nothing (Int32 ID)
  elem.Key: Not Nothing
  value: Nothing

したがって、data.Add が NullReferenceException をスローする理由はまったくないようです。

一部の人々が他の質問で示唆したように、スレッド化の問題がある可能性があります。ただし、私が書いている辞書は、定義上、1 つのスレッドにしか表示できません。(もちろん、ミニダンプもチェックして、同じコードを実行しているスレッドがないことを確認しました。)

この例外を黙って無視するかもしれませんが、むしろこれを理解したいと思います。

編集。興味のある方のために、ここにコード全体があります:

Private Function RowToType(ByVal row As DataRow) As DataSourceRow
    Dim o = _typeActivator({})
    Dim data As New Dictionary(Of String, Object)
    Dim elem As KeyValuePair(Of String, PropertyInfo) = Nothing
    Dim value As Object = Nothing
    Try
        For Each elem In _typeProperties
            value = row.Item(elem.Key)
            If DBNull.Value.Equals(value) Then value = Nothing
            elem.Value.SetValue(o, value, Nothing)
            data.Add(elem.Key, value)           ' NullReferenceException here
        Next
    Catch ex As Exception When RowToTypeExceptionFilter(ex, row, data, elem, value)
    End Try

    o.Data = data
    Return o
End Function

参考までに:動的型_typeActivatorのインスタンスを作成します 。oただし、それが問題とは何の関係もないと思います。

4

5 に答える 5

0

value: NothingNull 参照例外を取得する正当な理由になります。DataRow の文字列が Nothing である可能性があります (列が存在しない場合は、例外が発生します)。

于 2013-06-12T08:44:01.043 に答える
0

何気なくドコを見ている。

オブジェクト変数に Nothing を代入すると、オブジェクト インスタンスは参照されなくなります。変数が以前にインスタンスを参照していた場合、それを Nothing に設定してもインスタンス自体は終了しません。ガベージ コレクター (GC) がアクティブな参照が残っていないことを検出した後にのみ、インスタンスが終了し、それに関連付けられているメモリとシステム リソースが解放されます。

オブジェクトを「Nothing」に設定する前に、オブジェクトに有効な参照があるとシステムが判断する可能性があります。

これは、ディクショナリ値の設定の外部またはディクショナリ自体の内部で発生する可能性があります。キーにリンクされているオブジェクトは、設定されていると解放される場合があります。

于 2013-06-25T03:15:58.017 に答える
0

あなたの問題はここにあると思います.row.Item(elem.Key)、elem.keyは存在せず、それがnull例外をスローしているものです。row.Table.Columns.Contains(elem.key) を確認することで、列を確認できます。

于 2013-06-25T21:32:38.830 に答える