Lỗi ContextSwitchDeadlock đã được phát hiện trong C #


80

Tôi đang chạy ứng dụng C # và trong thời gian chạy, tôi gặp lỗi sau:

CLR không thể chuyển đổi từ ngữ cảnh COM 0x20e480 sang ngữ cảnh COM 0x20e5f0 trong 60 giây. Chủ đề sở hữu ngữ cảnh đích / căn hộ rất có thể đang thực hiện chờ đợi không bơm hoặc xử lý một hoạt động đang chạy rất lâu mà không cần bơm thông báo Windows. Tình trạng này thường có tác động tiêu cực đến hiệu suất và thậm chí có thể dẫn đến ứng dụng trở nên không phản hồi hoặc việc sử dụng bộ nhớ liên tục tích lũy theo thời gian. Để tránh sự cố này, tất cả các luồng căn hộ có luồng đơn (STA) nên sử dụng các nguyên tắc chờ bơm (chẳng hạn như CoWaitForMultipleHandles) và thường xuyên bơm thông báo trong các hoạt động chạy dài.

Bất cứ ai có thể vui lòng giúp tôi với vấn đề ở đây?

Cảm ơn rất nhiều.

Câu trả lời:


123

Chuỗi chính của chương trình của bạn đã bận thực thi mã trong một phút. Nó không chăm sóc các nhiệm vụ bình thường của nó, bơm vòng lặp thông điệp. Điều đó là bất hợp pháp khi bạn sử dụng máy chủ COM trong chuỗi công nhân: không thể gửi các lệnh gọi đến phương thức của chúng cho đến khi luồng chính của bạn không hoạt động nữa.

Nó sẽ dễ dàng nhìn thấy, giao diện người dùng của bạn sẽ chết như đinh đóng cột. Windows lẽ ra đã thay thế cửa sổ chính của bạn bằng một bản ma hiển thị "Không phản hồi". Đóng cửa sổ sẽ không hoạt động, không có sự kiện nhấp chuột nào có hiệu lực.

Thay vào đó, bất cứ điều gì luồng chính của bạn đang làm sẽ được thực hiện bởi một luồng công nhân. Các BackgroundWorkerlớp học là tốt cho điều đó, bạn sẽ tìm thấy nhiều sự giúp đỡ sử dụng trong bài viết MSDN Library cho nó. Sử dụng Debug + Break All, Debug + Windows + Threads nếu bạn không biết chuỗi chính đang làm gì.

Một nguyên nhân nữa có thể xảy ra: hãy đảm bảo cài đặt gói dịch vụ 1 nếu bạn đang sử dụng phiên bản RTM của VS2005.


5
+1 để giải thích rằng một mục công việc như vậy nên được chuyển sang một chuỗi phụ, do đó giải pháp về cách tránh lỗi này (thay vì chỉ những gì tạo ra lỗi).
JYelton

2
Điều thú vị là tôi đã thấy một số ứng dụng được xây dựng trong nhà khác bị treo lâu hơn của tôi nhưng tôi đã gặp phải thông báo lỗi này, hmmm.
Coops

Tài liệu MSDN: contextSwitchDeadlock MDA msdn.microsoft.com/en-us/library/ms172233%28v=vs.110%29.aspx
D_Bester

1
Cảm ơn bạn đã giải thích chi tiết Cách giải quyết mà tôi đã sử dụng là các hàm không đồng bộ, bây giờ có ý nghĩa hoàn hảo. Vì vậy, từ những gì tôi thu thập được, điều rất quan trọng là phải quản lý một luồng mới cho các hoạt động chạy lâu dài, đặc biệt là khi sử dụng COM.
Anthony Mason

50

Để tìm thao tác nào đang chặn công tắc ngữ cảnh và khiến MDA contextSwitchDeadlock được hiển thị, bạn có thể sử dụng các bước sau. Lưu ý rằng tôi sẽ đề cập đến Visual Studio 2012.

  1. Tạo lại lỗi. Điều này có thể liên quan đến một số thử nghiệm và sai sót.
  2. Nhấp vào 'OK' thay vì 'Tiếp tục' trong trợ lý Quản lý gỡ lỗi được hiển thị.
  3. Đảm bảo rằng thanh công cụ Vị trí gỡ lỗi đang hoạt động bằng cách nhấp chuột phải vào vùng gắn thanh công cụ và chọn 'Vị trí gỡ lỗi'. Bạn sẽ thấy một danh sách thả xuống có nhãn 'Chủ đề' trên thanh công cụ nếu nó đang hoạt động.
  4. Mục được chọn trong danh sách Chủ đề thả xuống phải là một chuỗi khác với chuỗi chính vì nó sẽ là một chuỗi nền phàn nàn rằng chuỗi chính đang thu hút tất cả sự chú ý. Chọn chủ đề chính trong danh sách thả xuống.
  5. Bây giờ bạn sẽ thấy mã đang chặn chuyển đổi ngữ cảnh trong trình chỉnh sửa mã.

Giả sử rằng bạn quyết định không chuyển hoạt động sử dụng nhiều tài nguyên ra khỏi chuỗi chính của mình - hãy xem một số câu trả lời và nhận xét khác tại đây trước khi thực hiện - bạn có các tùy chọn sau để vô hiệu hóa Hỗ trợ gỡ lỗi được quản lý.

Trong Trình gỡ lỗi Visual Studio

  1. Bạn có thể vô hiệu hóa MDA trực tiếp trong hộp thoại MDA được hiển thị khi lỗi xảy ra bằng cách bỏ chọn 'Ngắt khi loại ngoại lệ này được ném'.
  2. Với hộp thoại Cài đặt Ngoại lệ bằng cách sử dụng các hướng dẫn bên dưới từ MSDN .

... trên menu Gỡ lỗi, bấm vào Ngoại lệ. (Nếu menu Gỡ lỗi không chứa lệnh Ngoại lệ, hãy bấm Tùy chỉnh trên menu Công cụ để thêm lệnh đó.) Trong hộp thoại Ngoại lệ, hãy mở rộng danh sách Hỗ trợ gỡ lỗi được quản lý, rồi bỏ chọn hộp kiểm Thrown cho từng MDA.

Bên ngoài Trình gỡ lỗi Visual Studio

  1. Khóa đăng ký (Toàn máy, Tất cả MDA bị ảnh hưởng)
  2. Biến môi trường (Máy rộng, MDA có thể được chỉ định)
  3. Cài đặt cấu hình ứng dụng (Phạm vi ứng dụng, MDA có thể được chỉ định)

Lưu ý: Một trong hai tùy chọn đầu tiên phải được đặt thành 1 để tùy chọn thứ ba có hiệu lực.

Trong trường hợp của tôi, sự cố là một cuộc gọi tới ObjectContext.SaveChanges () trong Entity Framework trong một ứng dụng bảng điều khiển. Với MTAThreadAttribute được áp dụng cho Main()phương thức , ngoại lệ ContextSwitchDeadlock không còn được đưa ra nữa . Rất tiếc, tôi không chắc về những ảnh hưởng đầy đủ của thay đổi này.


2
ủng hộ cho lời giải thích rõ ràng về việc tìm mã chặn quy trình.
Guillaume Schuermans

10

Thông báo này cho biết một số mã của bạn đang cố gắng chuyển chuỗi và chuỗi đích đang bận. Ví dụ: một chuỗi nền đang cố gắng gửi một cuộc gọi đến chuỗi giao diện người dùng để cập nhật giao diện người dùng, trong khi giao diện người dùng đang chạy một vòng lặp chặt chẽ trong một thời gian.

Để thực sự tìm ra những gì đang xảy ra, bạn cần phải đột nhập vào trình gỡ lỗi và xem xét tất cả các chuỗi và những gì chúng đang làm.


4

Trong một số trường hợp:
Gỡ lỗi -> Ngoại lệ -> Hỗ trợ gỡ lỗi được quản lý
và bỏ chọn mục ContextSwitchDeadlock.


5
Có, nhưng khi bạn đang viết bài kiểm tra một lần và điều này cản trở bạn, thật tuyệt khi bạn có thể vô hiệu hóa nó.
Tod

4
Không sai. Đây không phải là một giải pháp cho vấn đề.
Tom W

3
Bạn phải nghĩ như một kỹ sư chứ không phải một nhà khoa học !!
Ehsan Zargar Ershadi

4
@Ehsan Ershadi, một kỹ sư giỏi dự đoán và khắc phục sự cố, không đẩy nó xuống dưới thảm!
Mo Patel

4
CƯỜI LỚN. Nếu bạn không muốn thấy lỗi, bạn có thể chỉ cần tìm ở một nơi khác ngoài màn hình của mình. Đây là cách tiếp cận tương tự với "giải pháp" của bạn. Đây không phải là một giải pháp. Đây chỉ là BỎ QUA!
tò mòBoy

0

Chỉ cần chọn Ngoại lệ từ trình đơn Gỡ lỗi trong cửa sổ visual studio 2005, hộp thoại Edxception sẽ bật lên, chọn Nút ngoại lệ hỗ trợ gỡ lỗi quản lý, sau đó chọn ContextSwitchDeadlock và loại bỏ lựa chọn khỏi cột Thrown. điều này sẽ ngăn vs ném ngoại lệ ContextSwitchDeadlock.

Hi vọng điêu nay co ich..


60
Cánh tay của bạn đang cháy. Đơn giản chỉ cần dùng dao để cắt dây thần kinh truyền cảm giác đau đến não của bạn. Điều này sẽ giúp bạn không nhận thấy rằng cánh tay của bạn đang bốc cháy.
Ozzah

Dù sao đây cũng là cách giải quyết vấn đề tạm thời. Để hoàn thành việc loại bỏ vấn đề này, cần một thời gian để xem xét lại về thiết kế của ứng dụng.
Wang Jijun

0

Tôi gặp phải vấn đề này khi tôi đang cố gắng tìm hiểu lý do tại sao tôi OracleDataReaderlại ném một ngoại lệ. Tôi nghĩ đó là do nó được gán nullvì ngoại lệ liên quan đến một tham số là `null. Tôi cũng vậy:

while (dr.Read())
{
    while (dr != null)  // <-- added this line
    {
      ...

Hóa ra drlà KHÔNG BAO GIỜ là rỗng và vì vậy vòng lặp cứ tiếp tục lặp đi lặp lại cho đến khi thông báo này đến, và tiếp tục lặp lại vì bạn có thể nhấp vào "Tiếp tục" để tiếp tục cho đến khi hết bộ nhớ (đừng làm như vậy - nhấp vào "OK" thay thế). Vì vậy, đạo đức của câu chuyện, hãy tìm những chỗ rò rỉ bộ nhớ đang truyền dữ liệu từ cơ sở dữ liệu vào bộ nhớ theo vòng lặp đến vô tận. Lỗi thực sự đang cố gắng cảnh báo bạn về một kịch bản xấu. Tốt nhất nên chú ý đến nó.


0

Lỗi này đã xuất hiện với tôi nhiều lần và tôi đã truy tìm nó đến một lần lặp lại DataGridViewRow, trong đó tôi đặt giá trị hộp kiểm thành true. Vì tôi đang chạy ở chế độ gỡ lỗi, tôi có tùy chọn để tiếp tục, vì vậy tôi có thể thực hiện việc này.

Tôi hi vọng điêu nay se giup được ai đo.


0

Giả sử bạn đang sử dụng Visual Studio, bạn có thể nhấp Ctrl+Alt+Evào dự án hiện tại và cửa sổ ngoại lệ sẽ hiển thị với Hỗ trợ gỡ lỗi được quản lý được chọn, bạn nên bỏ chọn tùy chọn "ContextSwitchDeadlock". sau đó xây dựng một dự án hiện tại.

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.