Visual Studio: ContextSwitchDeadlock

167

Saya mendapatkan pesan kesalahan yang tidak bisa saya selesaikan. Itu berasal dari Visual Studio atau debugger. Saya tidak yakin apakah kondisi kesalahan pamungkas ada di VS, debugger, program saya, atau database.

Ini adalah aplikasi Windows. Bukan aplikasi web.

Pesan pertama dari VS adalah kotak sembulan yang mengatakan: "Tidak ada simbol yang dimuat untuk bingkai tumpukan panggilan apa pun. Kode sumber tidak dapat ditampilkan." Ketika itu diklik, saya mendapatkan: " ContextSwitchDeadlock terdeteksi ", bersama dengan pesan panjang yang direproduksi di bawah.

Kesalahan muncul dalam satu loop yang memindai DataTable. Untuk setiap baris, ia menggunakan nilai kunci (HIC #) dari tabel sebagai parameter untuk SqlCommand. Perintah ini digunakan untuk membuat SqlDataReader yang mengembalikan satu baris. Data dibandingkan. Jika kesalahan terdeteksi, baris ditambahkan ke DataTable kedua.

Kesalahan tampaknya terkait dengan berapa lama prosedur berjalan (yaitu setelah 60 detik), bukan berapa banyak kesalahan yang ditemukan. Saya tidak berpikir itu masalah memori. Tidak ada variabel yang dideklarasikan dalam loop. Satu-satunya objek yang dibuat adalah SqlDataReaders, dan mereka menggunakan struktur. Tambahkan System.GC.Collect () tidak berpengaruh.

Db adalah situs SqlServer di laptop yang sama.

Tidak ada alat mewah atau gadget di Formulir.

Saya tidak mengetahui apa-apa dalam proc ini yang sangat berbeda dari apa yang telah saya lakukan puluhan kali sebelumnya. Saya telah melihat kesalahan sebelumnya, tetapi tidak pernah secara konsisten.

Ada ide, siapa saja?

Teks kesalahan penuh: CLR tidak dapat beralih dari konteks COM 0x1a0b88 ke konteks COM 0x1a0cf8 selama 60 detik. Utas yang memiliki konteks tujuan / apartemen kemungkinan besar melakukan menunggu tanpa memompa atau memproses operasi yang berjalan sangat lama tanpa memompa pesan Windows. Situasi ini umumnya memiliki dampak kinerja negatif dan bahkan dapat menyebabkan aplikasi menjadi tidak responsif atau penggunaan memori menumpuk terus-menerus dari waktu ke waktu. Untuk menghindari masalah ini, semua utas apartemen ulir tunggal (STA) harus menggunakan primitif menunggu pemompaan (seperti CoWaitForMultipleHandles) dan secara rutin memompa pesan selama operasi yang berjalan lama.

SeaDrive
sumber

Jawaban:

287

Itu ContextSwitchDeadlocktidak selalu berarti kode Anda memiliki masalah, hanya saja ada potensi. Jika Anda masuk ke Debug > Exceptionsdalam menu dan memperluas Managed Debugging Assistants, Anda akan menemukan ContextSwitchDeadlockdiaktifkan. Jika Anda menonaktifkan ini, VS tidak akan lagi memperingatkan Anda ketika item membutuhkan waktu lama untuk diproses. Dalam beberapa kasus, Anda mungkin memiliki operasi yang berjalan lama. Ini juga membantu jika Anda sedang men-debug dan berhenti pada jalur saat ini sedang diproses - Anda tidak ingin komplain sebelum Anda memiliki kesempatan untuk menggali masalah.

Pedro
sumber
4
Tepat! Terima kasih. Saya memang harus pergi ke Customize dan menambahkan Pengecualian ke menu Debug. Bukan aspek yang paling intuitif dari UI. Tools \ Customize, lalu Atur Ulang Perintah (tombol), lalu Pilih Debug dari drop-down di kanan atas, lalu Tambah (tombol). Wah!
SeaDrive
81
ctrl-alt-emembawa dialog pengecualian.
Florian Doyon
1
Banyak versi terbaru dari Visual Studio (2012, 2010, 2008) dan mungkin beberapa yang sebelumnya, memungkinkan seseorang untuk memilih penggunaan utama Visual Studio ketika pertama kali dijalankan setelah instalasi. Pilihan itu menentukan tata letak default bilah alat, termasuk kontrol mana yang terlihat atau disembunyikan, dan bahkan penekanan tombol mana yang sesuai dengan perintah mana. Di VS 2010, Wizard Pengaturan Impor dan Ekspor memungkinkan Anda untuk mengatur ulang ke salah satu default yang tersedia.
Zarepheth
4
@ B.ClayShannon - ContextSwitchDeadlock khusus untuk debugger. Versi rilis dari exe tidak akan menampilkan pesan ini.
Pedro
9
Di VS 2013 Navigasikan dengan Debug -> Windows -> Exceptions Settings. Kemudian gunakan pencarian
Markus Weber
16

Seperti kata Pedro, Anda memiliki masalah dengan debugger yang mencegah pompa pesan jika Anda melangkah melalui kode.

Tetapi jika Anda melakukan operasi yang berjalan lama pada utas UI, maka panggil Application.DoEvents () yang secara eksplisit memompa antrian pesan dan kemudian mengembalikan kontrol ke metode Anda saat ini.

Namun jika Anda melakukan ini, saya akan merekomendasikan untuk melihat desain Anda sehingga Anda dapat melakukan pemrosesan dari thread UI sehingga UI Anda tetap bagus dan cepat.

Tempat menyimpan bahan makanan
sumber
14

Sepertinya Anda melakukan ini pada utas UI utama di aplikasi. Utas UI bertanggung jawab untuk memompakan pesan windows sebagai kedatangan, namun karena Anda diblokir dalam panggilan basis data, ia tidak dapat melakukannya. Ini dapat menyebabkan masalah dengan pesan di seluruh sistem.

Anda harus melihat pemunculan utas latar belakang untuk operasi yang berjalan lama dan memasang semacam dialog "Saya sibuk" untuk pengguna saat itu terjadi.

Rob Walker
sumber
13

Di Visual Studio 2017, hapus centang opsi ContextSwitchDeadlock oleh:

Debug> Windows> Pengaturan Pengecualian

masukkan deskripsi gambar di sini

Dalam Pengecualian Pengaturan Windows: Hapus centang opsi ContextSwitchDeadlock

masukkan deskripsi gambar di sini

Hassan Rahman
sumber
9

Jika Anda tidak ingin menonaktifkan pengecualian ini, yang perlu Anda lakukan adalah membiarkan aplikasi Anda memompa beberapa pesan setidaknya sekali setiap 60 detik. Ini akan mencegah pengecualian ini terjadi. Coba panggil System.Threading.Thread.CurrentThread.Join (10) sesekali. Ada panggilan lain yang dapat Anda lakukan agar pesan memompa.


sumber
Bisakah Anda menjelaskan mengapa ini membantu?
menggulung
Ini tidak akan berfungsi, saya memiliki loop memperbarui UI dan masih mendapatkan pesan kesalahan.
htm11h
1
Tidak perlu menggunakan nilai 10 milidetik, bahkan jika Anda bermaksud menyebutnya berulang dalam operasi yang berjalan lama, itu akan mengurangi kinerja keseluruhan (eksekusi total waktu) banyak. Cukup berikan nol untuk itu.
ElektroStudios
Saya punya masalah serupa. Menemukan solusi Anda untuk berfungsi. Terima kasih!
Sk Shahnawaz-ul Haque
2

Solusi di atas baik dalam beberapa skenario tetapi ada skenario lain di mana ini terjadi ketika Anda menguji unit dan Anda mencoba "Debug Selected Tests" dari Test Explorer ketika solusi Anda tidak disetel ke Debug.

Dalam hal ini Anda perlu mengubah solusi Anda dari Release atau apa pun itu diatur ke Debug dalam kasus ini. Jika ini masalahnya, maka mengubah "ContextSwitchDeadlock" tidak akan membantu Anda.

Saya melewatkan ini sendiri karena pesan kesalahannya sangat buruk sehingga saya tidak memeriksa hal yang sudah jelas yaitu pengaturan Debug!

Ewan
sumber
1

Dalam Visual Studio 2017 versi Spanyol.

"Depurar" -> "Ventanas" -> "Configuración de Excepciones"

dan cari "ContextSwitchDeadlock". Lalu, hapus centang. Atau jalan pintas

Ctrl + D, E

Terbaik.

kahonmlg
sumber
0

Anda dapat menyelesaikan ini dengan menghapus centang pada kontekstandar yang terkunci dari

Debug-> Pengecualian ... -> Perluas simpul MDA -> hapus centang -> contextswitchdeadlock

KR Akhil
sumber
0

Saya mendapatkan kesalahan ini dan mengalihkan kueri ke async (tunggu (...). ToListAsync ()). Semuanya baik sekarang.

dunwan
sumber