Visual Studio: ContextSwitchDeadlock


167

ฉันได้รับข้อความแสดงข้อผิดพลาดที่ไม่สามารถแก้ไขได้ มันมาจาก Visual Studio หรือดีบักเกอร์ ฉันไม่แน่ใจว่าเงื่อนไขข้อผิดพลาดขั้นสุดท้ายอยู่ใน VS, ดีบักเกอร์, โปรแกรมของฉันหรือฐานข้อมูล

นี่คือแอพ Windows ไม่ใช่เว็บแอป

ข้อความแรกจาก VS คือกล่องป๊อปอัพที่พูดว่า: "ไม่มีสัญลักษณ์ถูกโหลดสำหรับกรอบการโทรสแต็คใด ๆ รหัสแหล่งที่มาไม่สามารถแสดงได้" เมื่อคลิกแล้วฉันจะได้รับ: " ตรวจพบ ContextSwitchDeadlock " พร้อมกับข้อความยาวที่ทำซ้ำด้านล่าง

ข้อผิดพลาดเกิดขึ้นในการวนรอบที่สแกน DataTable สำหรับแต่ละบรรทัดจะใช้ค่าคีย์ (HIC #) จากตารางเป็นพารามิเตอร์สำหรับ SqlCommand คำสั่งถูกใช้เพื่อสร้าง SqlDataReader ซึ่งส่งคืนหนึ่งบรรทัด เปรียบเทียบข้อมูล หากตรวจพบข้อผิดพลาดแถวจะถูกเพิ่มไปยัง DataTable ที่สอง

ดูเหมือนว่าข้อผิดพลาดจะเกี่ยวข้องกับระยะเวลาที่โพรซีเดอร์ใช้ในการรัน (เช่นหลังจาก 60 วินาที) ไม่พบข้อผิดพลาดจำนวนเท่าใด ฉันไม่คิดว่ามันเป็นปัญหาหน่วยความจำ ไม่มีการประกาศตัวแปรภายในลูป วัตถุเท่านั้นที่สร้างขึ้นคือ SqlDataReaders และพวกเขาอยู่ในการใช้โครงสร้าง เพิ่ม System.GC.Collect () ไม่มีผลใด ๆ

db เป็นไซต์ SqlServer บนแล็ปท็อปเครื่องเดียวกัน

ไม่มี gizmos แฟนซีหรือแกดเจ็ตในแบบฟอร์ม

ฉันไม่รู้อะไรเลยใน proc นี้ซึ่งแตกต่างอย่างมากจากสิ่งที่ฉันทำมาหลายสิบครั้งก่อน ฉันเคยเห็นข้อผิดพลาดมาก่อน แต่ไม่เคยอยู่บนพื้นฐานที่สอดคล้องกัน

ความคิดใด ๆ ใคร

ข้อความแสดงข้อผิดพลาดแบบเต็ม: CLR ไม่สามารถเปลี่ยนจากบริบท COM 0x1a0b88 เป็นบริบท COM 0x1a0cf8 เป็นเวลา 60 วินาที เธรดที่เป็นเจ้าของบริบท / อพาร์ทเมนต์ปลายทางส่วนใหญ่มีแนวโน้มที่จะทำการรอปั๊มหรือการดำเนินการที่ใช้เวลานานโดยไม่ต้องปั๊มข้อความ Windows สถานการณ์นี้โดยทั่วไปมีผลกระทบด้านลบต่อประสิทธิภาพและอาจทำให้แอปพลิเคชันไม่ตอบสนองหรือการใช้หน่วยความจำสะสมอย่างต่อเนื่องเมื่อเวลาผ่านไป เพื่อหลีกเลี่ยงปัญหานี้เธรดอพาร์ทเมนต์เธรดเดียวทั้งหมด (STA) ควรใช้การปั๊มแบบดั้งเดิมที่รอคอย (เช่น CoWaitForMultipleHandles) และปั๊มข้อความเป็นประจำในระหว่างการดำเนินการที่ยาวนาน

คำตอบ:


287

ContextSwitchDeadlockไม่ได้หมายความว่ารหัสของคุณมีปัญหาเพียงแค่ว่ามีศักยภาพ หากคุณไปDebug > Exceptionsที่เมนูและขยายManaged Debugging Assistantsคุณจะพบว่าContextSwitchDeadlockมีการเปิดใช้งาน หากคุณปิดใช้งานสิ่งนี้ VS จะไม่เตือนคุณเมื่อรายการใช้เวลานานในการประมวลผล ในบางกรณีคุณอาจมีการดำเนินการที่ยาวนาน นอกจากนี้ยังมีประโยชน์หากคุณกำลังดีบั๊กและหยุดสายขณะที่กำลังประมวลผลอยู่ - คุณไม่ต้องการให้บ่นก่อนที่คุณจะมีโอกาสขุดลงในปัญหา


4
ถูกต้อง! ขอบคุณ ฉันต้องไปที่กำหนดเองและเพิ่มข้อยกเว้นในเมนูดีบั๊ก ไม่ใช่แง่มุมที่เข้าใจง่ายที่สุดของ UI Tools \ Customize จากนั้นจัดเรียงคำสั่ง (ปุ่ม) จากนั้นเลือก Debug จากดรอปดาวน์ที่มุมขวาบนจากนั้นเพิ่ม (ปุ่ม) ต๊าย!
SeaDrive

81
ctrl-alt-eนำมาซึ่งกล่องโต้ตอบข้อยกเว้น
Florian Doyon

1
Visual Studio รุ่นล่าสุดจำนวนมาก (2012, 2010, 2008) และอาจเป็นรุ่นก่อนหน้าบางรุ่นให้เลือกใช้ Visual Studio เป็นหลักเมื่อเรียกใช้ครั้งแรกหลังการติดตั้ง ตัวเลือกนั้นจะกำหนดเค้าโครงเริ่มต้นของแถบเครื่องมือซึ่งรวมถึงตัวควบคุมที่สามารถมองเห็นหรือซ่อนได้และการกดแป้นที่สอดคล้องกับคำสั่งใด ใน VS 2010 ตัวช่วยสร้างการตั้งค่าการนำเข้าและส่งออกอนุญาตให้คุณรีเซ็ตเป็นค่าเริ่มต้นที่มีอยู่อย่างใดอย่างหนึ่ง
Zarepheth

4
@ B.ClayShannon - ContextSwitchDeadlock เป็นค่าเฉพาะสำหรับดีบักเกอร์ รุ่นที่วางจำหน่ายของ exe จะไม่แสดงข้อความนี้
Pedro

9
ใน VS 2013 Debug -> Windows -> Exceptions Settingsนำทางด้วย จากนั้นใช้การค้นหา
Markus Weber

16

ดังที่เปโดรกล่าวว่าคุณมีปัญหากับตัวดีบักเกอร์ที่ป้องกันปั๊มข้อความหากคุณกำลังก้าวผ่านโค้ด

แต่ถ้าคุณทำการดำเนินการที่รันเป็นเวลานานบนเธรด UI ให้เรียก Application.DoEvents () ซึ่งจะปั๊มคิวข้อความอย่างชัดเจนจากนั้นส่งคืนการควบคุมไปยังวิธีการปัจจุบันของคุณ

อย่างไรก็ตามถ้าคุณทำเช่นนี้ฉันขอแนะนำให้ดูที่การออกแบบของคุณเพื่อให้คุณสามารถดำเนินการปิดเธรด UI เพื่อให้ UI ของคุณยังคงสวยงาม


14

ดูเหมือนว่าคุณกำลังทำสิ่งนี้ในเธรด UI หลักในแอป เธรด UI รับผิดชอบการปั๊มข้อความ windows เมื่อมาถึงและเนื่องจากคุณถูกบล็อกในการโทรฐานข้อมูลจึงไม่สามารถทำได้ สิ่งนี้อาจทำให้เกิดปัญหากับข้อความทั่วทั้งระบบ

คุณควรดูที่การวางไข่เธรดพื้นหลังสำหรับการดำเนินการที่ใช้เวลานานและวางกล่องโต้ตอบ "ฉันไม่ว่าง" ให้กับผู้ใช้ในขณะที่มันเกิดขึ้น


13

ใน Visual Studio 2017 ยกเลิกการเลือกตัวเลือก ContextSwitchDeadlock โดย:

แก้ไขข้อบกพร่อง> Windows> การตั้งค่าข้อยกเว้น

ป้อนคำอธิบายรูปภาพที่นี่

ในการตั้งค่าข้อยกเว้น Windows: ยกเลิกการเลือกตัวเลือก ContextSwitchDeadlock

ป้อนคำอธิบายรูปภาพที่นี่


9

หากคุณไม่ต้องการปิดใช้งานข้อยกเว้นนี้สิ่งที่คุณต้องทำคือให้แอปพลิเคชันของคุณปั๊มข้อความอย่างน้อยหนึ่งครั้งทุก ๆ 60 วินาที มันจะป้องกันข้อยกเว้นนี้ให้เกิดขึ้น ลองโทร System.Threading.Thread.CurrentThread.Join (10) นาน ๆ มีการโทรอื่น ๆ ที่คุณสามารถทำได้เพื่อให้ข้อความปั๊ม


คุณช่วยอธิบายได้ไหมว่าทำไมสิ่งนี้ถึงช่วยได้
ม้วน

ใช้งานไม่ได้ฉันมีการอัปเดตลูป UI และยังได้รับข้อความแสดงข้อผิดพลาด
htm11h

1
ไม่จำเป็นต้องใช้ค่า 10 มิลลิวินาทีในความเป็นจริงถ้าคุณตั้งใจจะเรียกมันซ้ำ ๆ ในการทำงานที่ยาวนานซึ่งจะลดประสิทธิภาพโดยรวม (การดำเนินการตามเวลาทั้งหมด) จำนวนมาก เพียงแค่ผ่านศูนย์ไป
ElektroStudios

ฉันมีปัญหาที่คล้ายกัน พบวิธีแก้ปัญหาของคุณที่จะทำงาน ขอบคุณ!
Sk Shahnawaz-ul Haque

2

วิธีแก้ปัญหาข้างต้นดีในบางสถานการณ์ แต่มีสถานการณ์อื่นที่เกิดขึ้นเมื่อคุณทำการทดสอบหน่วยและคุณพยายาม "Debug Selected Tests" จาก Test Explorer เมื่อโซลูชันของคุณไม่ได้ตั้งค่าเป็น Debug

ในกรณีนี้คุณต้องเปลี่ยนโซลูชันจาก Release หรืออะไรก็ตามที่ตั้งค่าเป็น Debug ในกรณีนี้ หากนี่คือปัญหาแล้วการเปลี่ยน "ContextSwitchDeadlock" จะไม่ช่วยคุณจริงๆ

ฉันพลาดสิ่งนี้เพราะข้อความแสดงข้อผิดพลาดน่ารังเกียจมากฉันไม่ได้ตรวจสอบสิ่งที่ชัดเจนซึ่งเป็นการตั้งค่าการดีบัก!


1

ใน Visual Studio 2017 เวอร์ชั่นภาษาสเปน

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

และค้นหา "ContextSwitchDeadlock" จากนั้นให้ยกเลิกการเลือก หรือทางลัด

Ctrl + D, E

ดีที่สุด


0

คุณสามารถแก้ปัญหานี้ได้โดยยกเลิกการเลือกบริบทที่ล็อคจาก

Debug-> ข้อยกเว้น ... -> ขยายโหนด MDA -> ยกเลิกการเลือก -> contextswitchdeadlock


0

ฉันได้รับข้อผิดพลาดนี้และเปลี่ยนแบบสอบถามเป็น async (await (... ). ToListAsync ()) ทั้งหมดนี้ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.