2013-01-02 26 views
6

NullReferenceException jest wyrzucane na linii, na której wszystkie zaangażowane obiekty są ważne. StackTrace pokazuje linia # jest 432.NullReferenceException podczas obiekty zaangażowane są ważne

Kod jest

enter image description here

Tutaj Flags i tempFlags oba są DataTables. Typy danych kolumn obu datatables są prymitywne (dziesiętne, datetime, krótkie). Aplikacja jest aplikacją wielowątkową, a fragment kodu należy do funkcji wątku. Flags jest decalred na przykład poziomu to znaczy wspólną wszystkich nici podczas tempFlags deklaruje wewnątrz funkcji nici.

Tutaj w tym szczególnym przypadku czasu Flags zawiera 1946 rekordów i tempFlags zawiera 1. Dlaczego jest to wyjątek NullReferenceException?

Edit # 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" 

Edit # 2

Wygląda oświadczenie Merge nie jest wątku bezpieczne jak po oddaniu linii 432 wewnątrz zamka, wyjątek nie ma, jak dotąd .

+0

Używasz blokady dla tempFlags? podczas czyszczenia plików tymczasowych. – Adil

+1

Czy możesz zamieścić szczegóły wyjątku? Wewnętrzny wyjątek, ślad stosu itp. – ryadavilli

+0

@Adil Nie powinno mieć znaczenia, prawda? Wyjątek jest zgłaszany przed tą linią, a 'tempFlags' jest lokalną zmienną w metodzie. –

Odpowiedz

1

wyjaśnienie tego wyjątku (IMO) specyficznego dla tego fragmentu kodu.

Pozwala nam powiedzieć wątek A jest wykonanie Scalanie i przechodzi DataTable Dt1, który jest przechowywany w seryjnej jako referenceToDatatable tymczasem

Wątek B przychodzi i przechodzi Dt2 do Merge który jest przechowywany w Merge jak referenceToDatatable (odnosi się to bo sama nie prymitywne obiekty są przekazywane przez refernce, Merge nie jest wątku bezpieczne i nie ma blokady) i stąd Dt1 jest zastępowany przez Dt2.

Do tej pory nie ma wyjątku, ponieważ Dt2 ma taką samą strukturę i nie jest to null.

Teraz wątek B jest zawieszony, a wątek A wchodzi, kończy się Merge i kończy działanie, a tym samym unieważnia Dt1, co również niweczy referenceToDatatable.

Teraz przełóż B przychodzi i stwierdza referenceToDatatable = null ->Wyjątek

2

Ponieważ wydaje się dzieje podczas wstawiania nowego wiersza, System.Data.DataTable.InsertRow(DataRow row, Int64 proposedID) Przypuszczam istnieje ograniczenie mówiąc pole nie może być puste. Próbujesz wstawić wartość null z tabeli źródłowej.

Albo, istnieje kolumna obliczeniowa i jedna z kolumn wejściowych jest null.

+0

Ta [odpowiedź] (http://stackoverflow.com/a/490569/649524) sugeruje środki zapobiegawcze dla tego problemu. – Tilak

2

Zawsze, gdy otrzymujesz NullReferenceException z wewnątrz i wielowątkowość, to prawie na pewno problem z bezpieczeństwem wątków, w którym nie stosuje się blokad tam, gdzie powinno być.

+0

Powoduje spowolnienie działania, ponieważ funkcja długiego życia ramy nie jest bezpieczna dla wątków !!! – bjan

+1

@bjan O ile przedmioty nie stanowią gwarancji bezpieczeństwa w dokumentacji, nie można ich bezpiecznie używać bez odpowiednich zabezpieczeń/barier/środków ostrożności. * Nie różni się to od 99 +% kodu napisanego przeze mnie (lub ciebie), który nie jest bezpieczny dla wątków, ponieważ nie został do tego specjalnie zaprojektowany. * Nie obwiniaj kodu, który jest używany poza jego umownymi granicami. (Chciałbym tylko pozwolić, aby jeden wątek miał dostęp do DT w dowolnym momencie za pomocą prostej blokady - lub lepiej, niech tylko jeden wątek "posiada" ID w danym momencie - i zobacz, czy to "naprawia" obserwowane problemy. "Najszybszy".) –