Otrzymuję komunikat o błędzie, którego nie mogę rozwiązać. Pochodzi z programu Visual Studio lub debugera. Nie jestem pewien, czy ostateczny stan błędu występuje w VS, debugerze, moim programie czy bazie danych.
To jest aplikacja dla systemu Windows. To nie jest aplikacja internetowa.
Pierwsza wiadomość od VS to wyskakujące okienko z informacją: „Żadne symbole nie są ładowane dla żadnej ramki stosu wywołań. Nie można wyświetlić kodu źródłowego”. Po kliknięciu otrzymuję komunikat: „ Wykryto ContextSwitchDeadlock ” wraz z długim komunikatem przedstawionym poniżej.
Błąd pojawia się w pętli, która skanuje w dół DataTable. Dla każdego wiersza używa wartości klucza (HIC #) z tabeli jako parametru dla SqlCommand. Polecenie służy do tworzenia SqlDataReader, który zwraca jeden wiersz. Dane są porównywane. W przypadku wykrycia błędu wiersz jest dodawany do drugiego DataTable.
Wydaje się, że błąd jest związany z tym, jak długo trwa procedura (tj. Po 60 sekundach), a nie z liczbą znalezionych błędów. Nie sądzę, żeby to był problem z pamięcią. W pętli nie są deklarowane żadne zmienne. Jedynymi obiektami, które są tworzone, są SqlDataReaders i są one w użyciu struktur. Dodanie System.GC.Collect () nie przyniosło żadnego efektu.
Baza danych to witryna SqlServer na tym samym laptopie.
W formularzu nie ma żadnych fantazyjnych gadżetów ani gadżetów.
Nie jestem świadomy niczego w tym procie, co znacznie różni się od tego, co robiłem dziesiątki razy wcześniej. Widziałem ten błąd wcześniej, ale nigdy w sposób spójny.
Jakieś pomysły, ktoś?
Pełny tekst błędu: CLR nie może przejść z kontekstu COM 0x1a0b88 do kontekstu COM 0x1a0cf8 przez 60 sekund. Wątek będący właścicielem kontekstu / apartamentu docelowego najprawdopodobniej albo wykonuje oczekiwanie bez pompowania, albo przetwarza bardzo długotrwałą operację bez pompowania komunikatów systemu Windows. Ta sytuacja ogólnie ma negatywny wpływ na wydajność i może nawet prowadzić do braku odpowiedzi aplikacji lub ciągłego zwiększania się zużycia pamięci. Aby uniknąć tego problemu, wszystkie wątki z pojedynczym wątkiem (STA) powinny używać elementów podstawowych oczekiwania pompowania (takich jak CoWaitForMultipleHandles) i rutynowo pompować komunikaty podczas długotrwałych operacji.
źródło
ctrl-alt-e
wyświetla okno dialogowe wyjątków.Debug -> Windows -> Exceptions Settings
. Następnie użyj wyszukiwaniaJak powiedział Pedro, masz problem z debugerem uniemożliwiającym pompowanie komunikatów, jeśli przechodzisz przez kod.
Ale jeśli wykonujesz długotrwałą operację w wątku interfejsu użytkownika, wywołaj Application.DoEvents (), która jawnie pompuje kolejkę komunikatów, a następnie zwraca sterowanie do bieżącej metody.
Jeśli jednak to robisz, zalecałbym przyjrzenie się projektowi, abyś mógł wykonać przetwarzanie poza wątkiem interfejsu użytkownika, aby interfejs użytkownika pozostał ładny i zgryźliwy.
źródło
Wygląda na to, że robisz to w głównym wątku interfejsu użytkownika w aplikacji. Wątek interfejsu użytkownika jest odpowiedzialny za pompowanie wiadomości systemu Windows w momencie ich nadejścia, ale ponieważ Twój jest blokowany w wywołaniach bazy danych, nie może tego zrobić. Może to powodować problemy z komunikatami w całym systemie.
Powinieneś przyjrzeć się tworzeniu wątku w tle dla długotrwałej operacji i wyświetlaniu pewnego rodzaju okna dialogowego „Jestem zajęty” dla użytkownika, gdy to się dzieje.
źródło
W programie Visual Studio 2017 odznaczono opcję ContextSwitchDeadlock przez:
Debuguj> Windows> Ustawienia wyjątków
W systemie Windows ustawień wyjątków: usuń zaznaczenie opcji ContextSwitchDeadlock
źródło
Jeśli nie chcesz wyłączać tego wyjątku, wszystko, co musisz zrobić, to pozwolić aplikacji pompować niektóre wiadomości co najmniej raz na 60 sekund. Zapobiegnie to wystąpieniu tego wyjątku. Spróbuj wywołać System.Threading.Thread.CurrentThread.Join (10) raz na jakiś czas. Istnieją inne połączenia, które możesz wykonać, aby wiadomości były pompowane.
źródło
Powyższe rozwiązanie jest dobre w niektórych scenariuszach, ale istnieje inny scenariusz, w którym dzieje się tak, gdy przeprowadzasz testy jednostkowe i próbujesz „Debugować wybrane testy” z Eksploratora testów, gdy rozwiązanie nie jest ustawione na debugowanie.
W takim przypadku musisz zmienić rozwiązanie z wydania lub cokolwiek, co jest ustawione na debugowanie w tym przypadku. Jeśli na tym polega problem, zmiana „ContextSwitchDeadlock” tak naprawdę nie pomoże.
Sam to przegapiłem, ponieważ komunikat o błędzie był tak nieprzyjemny, że nie sprawdziłem oczywistej rzeczy, jaką było ustawienie debugowania!
źródło
W hiszpańskiej wersji programu Visual Studio 2017.
i wyszukaj „ContextSwitchDeadlock”. Następnie odznacz to. Lub skrót
Najlepsza.
źródło
Możesz rozwiązać ten problem, odznaczając opcję contextswitchdeadlock z
Debuguj -> Wyjątki ... -> Rozwiń węzeł MDA -> odznacz -> contextswitchdeadlock
źródło
Otrzymałem ten błąd i przełączyłem zapytania na async (await (...). ToListAsync ()). Teraz wszystko w porządku.
źródło