Visual Studio: ContextSwitchDeadlock


167

Tôi đã nhận được một thông báo lỗi mà tôi không thể giải quyết. Nó bắt nguồn từ Visual Studio hoặc trình gỡ lỗi. Tôi không chắc liệu điều kiện lỗi cuối cùng là ở VS, trình gỡ lỗi, chương trình của tôi hay cơ sở dữ liệu.

Đây là một ứng dụng Windows. Không phải là một ứng dụng web.

Thông báo đầu tiên từ VS là một hộp bật lên có nội dung: "Không có biểu tượng nào được tải cho bất kỳ khung ngăn xếp cuộc gọi nào. Không thể hiển thị mã nguồn." Khi nhấp vào đó, tôi nhận được: " ContextSwitchDeadlock đã được phát hiện ", cùng với một thông báo dài được sao chép bên dưới.

Lỗi phát sinh trong một vòng lặp quét xuống DataTable. Đối với mỗi dòng, nó sử dụng một giá trị khóa (HIC #) từ bảng làm tham số cho SqlCommand. Lệnh được sử dụng để tạo SqlDataReader trả về một dòng. Dữ liệu được so sánh. Nếu phát hiện lỗi, một hàng được thêm vào DataTable thứ hai.

Lỗi dường như liên quan đến thời gian quy trình chạy trong bao lâu (tức là sau 60 giây), chứ không phải tìm thấy bao nhiêu lỗi. Tôi không nghĩ đó là vấn đề về trí nhớ. Không có biến được khai báo trong vòng lặp. Các đối tượng duy nhất được tạo ra là SqlDataReaders và chúng đang sử dụng các cấu trúc. Thêm System.GC.Collect () không có hiệu lực.

Db là một trang web SqlServer trên cùng một máy tính xách tay.

Không có gizmos ưa thích hoặc tiện ích trên Mẫu.

Tôi không biết bất cứ điều gì trong Proc này khác rất nhiều so với những gì tôi đã làm hàng chục lần trước đây. Tôi đã thấy lỗi trước đây, nhưng không bao giờ trên cơ sở nhất quán.

Có ai có ý kiến ​​gì không?

Lỗi đầy đủ Văn bản: CLR đã không thể chuyển từ bối cảnh COM 0x1a0b88 sang bối cảnh COM 0x1a0cf8 trong 60 giây. Chủ đề sở hữu bối cảnh / căn hộ đích rất có thể là thực hiện chờ không bơm hoặc xử lý một hoạt động chạy rất dài mà không cần bơm các thông điệp Windows. Tình trạng này thường có tác động hiệu quả tiêu cực và thậm chí có thể dẫn đến việc ứng dụng trở nên không đáp ứng hoặc sử dụng bộ nhớ tích lũy liên tục theo thời gian. Để tránh vấn đề này, tất cả các luồng căn hộ đơn luồng (STA) nên sử dụng các nguyên hàm bơm chờ (như CoWaitForMult MônHandles) và thường xuyên bơm tin nhắn trong các hoạt động chạy dài.

Câu trả lời:


287

Điều ContextSwitchDeadlocknày không nhất thiết có nghĩa là mã của bạn có vấn đề, chỉ là có tiềm năng. Nếu bạn đi đến Debug > Exceptionstrong menu và mở rộng Managed Debugging Assistants, bạn sẽ thấy ContextSwitchDeadlockđược kích hoạt. Nếu bạn tắt tính năng này, VS sẽ không còn cảnh báo bạn khi các mục đang mất nhiều thời gian để xử lý. Trong một số trường hợp, bạn có thể có một hoạt động dài hạn. Nó cũng hữu ích nếu bạn đang gỡ lỗi và dừng trên một dòng trong khi điều này đang xử lý - bạn không muốn nó phàn nàn trước khi bạn có cơ hội tìm hiểu vấn đề.


4
Đúng rồi! Cảm ơn. Tôi đã phải đi đến Tùy chỉnh và thêm Ngoại lệ vào menu Gỡ lỗi. Không phải là khía cạnh trực quan nhất của giao diện người dùng. Công cụ \ Tùy chỉnh, sau đó Sắp xếp lại các lệnh (nút), sau đó chọn Gỡ lỗi từ trình đơn thả xuống ở phía trên bên phải, sau đó Thêm (nút). Phù!
SeaDrive

81
ctrl-alt-emang đến hộp thoại ngoại lệ.
Florian Doyon

1
Nhiều phiên bản gần đây của Visual Studio (2012, 2010, 2008) và có thể một số phiên bản trước đó, cho phép một người chọn sử dụng chính Visual Studio khi lần đầu tiên chạy sau khi cài đặt. Lựa chọn đó xác định bố cục mặc định của các thanh công cụ, bao gồm các điều khiển được hiển thị hoặc ẩn và thậm chí các tổ hợp phím nào tương ứng với các lệnh nào. Trong VS 2010, Trình hướng dẫn Cài đặt Nhập và Xuất cho phép bạn đặt lại về một trong các giá trị mặc định khả dụng.
Zarepheth

4
@ B.ClayShannon - ContextSwitchDeadlock dành riêng cho trình gỡ lỗi. Phiên bản phát hành của exe sẽ không hiển thị thông báo này.
Pedro

9
Trong VS 2013 Điều hướng với Debug -> Windows -> Exceptions Settings. Sau đó sử dụng tìm kiếm
Markus Weber

16

Như Pedro đã nói, bạn có một vấn đề với trình gỡ lỗi ngăn chặn bơm thông báo nếu bạn đang chuyển qua mã.

Nhưng nếu bạn đang thực hiện một thao tác chạy dài trên luồng UI, thì hãy gọi Application.DoEvents () để bơm rõ ràng hàng đợi tin nhắn và sau đó trả lại quyền điều khiển cho phương thức hiện tại của bạn.

Tuy nhiên nếu bạn đang làm điều này, tôi khuyên bạn nên xem thiết kế của bạn để bạn có thể thực hiện xử lý tắt luồng UI để giao diện người dùng của bạn vẫn đẹp và linh hoạt.


14

Có vẻ như bạn đang làm điều này trên luồng UI chính trong ứng dụng. Chủ đề UI chịu trách nhiệm bơm các thông báo windows khi đến nơi, nhưng do bạn bị chặn trong các cuộc gọi cơ sở dữ liệu nên không thể thực hiện được. Điều này có thể gây ra vấn đề với các tin nhắn toàn hệ thống.

Bạn nên xem xét việc tạo ra một luồng nền cho hoạt động chạy dài và đưa ra một loại hộp thoại "Tôi đang bận" cho người dùng trong khi nó xảy ra.


13

Trong Visual Studio 2017, bỏ chọn tùy chọn ContextSwitchDeadlock bằng cách:

Gỡ lỗi> Windows> Cài đặt ngoại lệ

nhập mô tả hình ảnh ở đây

Trong Cài đặt ngoại lệ Windows: Bỏ chọn tùy chọn ContextSwitchDeadlock

nhập mô tả hình ảnh ở đây


9

Nếu bạn không muốn tắt ngoại lệ này, tất cả những gì bạn cần làm là để ứng dụng của bạn bơm một số tin nhắn ít nhất một lần sau mỗi 60 giây. Nó sẽ ngăn chặn ngoại lệ này xảy ra. Hãy thử gọi System.Threading.Thread.CảnThread.Join (10) thỉnh thoảng. Có những cuộc gọi khác bạn có thể làm điều đó để cho tin nhắn được bơm.


Bạn có thể giải thích tại sao điều này giúp?
cuộn

Điều này sẽ không hoạt động, tôi có một giao diện người dùng cập nhật vòng lặp và vẫn nhận được thông báo lỗi.
htm11h

1
Không cần sử dụng giá trị 10 mili giây, trên thực tế nếu bạn có ý định gọi nó lặp đi lặp lại trong một hoạt động dài, điều đó sẽ làm giảm hiệu suất tổng thể (tổng thời gian thực hiện) rất nhiều. Chỉ cần vượt qua nó cho nó.
ElektroStudios

Tôi đã có vấn đề tương tự. Tìm thấy giải pháp của bạn để được làm việc. Cảm ơn!
Sk Shahnawaz-ul Haque

2

Giải pháp trên là tốt trong một số trường hợp nhưng có một kịch bản khác xảy ra khi bạn đang thử nghiệm đơn vị và bạn cố gắng "Gỡ lỗi các thử nghiệm đã chọn" từ Test Explorer khi giải pháp của bạn không được đặt thành Gỡ lỗi.

Trong trường hợp này, bạn cần thay đổi giải pháp của mình từ Bản phát hành hoặc bất cứ điều gì nó được đặt thành Gỡ lỗi trong trường hợp này. Nếu đây là vấn đề thì việc thay đổi "ContextSwitchDeadlock" sẽ không thực sự giúp bạn.

Tôi đã bỏ lỡ điều này vì thông báo lỗi rất khó chịu. Tôi đã không kiểm tra điều hiển nhiên đó là cài đặt Gỡ lỗi!


1

Trong Visual Studio 2017 phiên bản tiếng Tây Ban Nha.

"Depurar" -> "Lỗ thông hơi" -> "Configuración de Excepciones"

và tìm kiếm "ContextSwitchDeadlock". Sau đó, bỏ chọn nó. Hoặc phím tắt

Ctrl + D, E

Tốt.


0

Bạn có thể giải quyết điều này bằng cách bỏ chọn contextswitchdeadlock từ

Gỡ lỗi-> Ngoại lệ ... -> Mở rộng nút MDA -> bỏ chọn -> contextswitchdeadlock


0

Tôi đã gặp lỗi này và chuyển các truy vấn sang async (await (...). ToListAsync ()). Tất cả đều tốt

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.