2010-10-19 28 views
20

Tôi đã gỡ lỗi một ứng dụng và một nơi nào đó trong mã, một chuỗi cố gắng truy cập vào hộp danh sách được tạo bởi một chuỗi khác. Khi cố gắng truy cập vào hộp danh sách, ứng dụng sẽ ném "hoạt động Cross-thread không hợp lệ: Kiểm soát 'listbox' được truy cập từ một chủ đề khác với chuỗi được tạo trên" ngoại lệ trong khi gỡ lỗi. Tuy nhiên, khi tôi chạy đầu ra của ứng dụng này trong thư mục bin \ Debug, tôi không nhận được hộp thoại ngoại lệ và tôi có thể thấy rằng hộp danh sách được truy cập thành công từ chuỗi không phải chủ sở hữu, vì vậy điều này khiến tôi nghĩ rằng có sự khác biệt về hành vi ở đây , không chỉ là một ngoại lệ bị đàn áp. Tôi có thể vượt qua ngoại lệ này khi gỡ lỗi bằng dòng sau trong sự kiện form_loadTại sao ngoại lệ thao tác chéo không được ném trong khi chạy exe trong bin Debug

Control.CheckForIllegalCrossThreadCalls = false; 

Nhưng lý do đằng sau hành vi khác này là gì?

Trả lời

36

Có, điều này chỉ được kiểm tra khi trình gỡ lỗi được đính kèm. Điều này là cần thiết vì có mã .NET 1.x vi phạm quy tắc này. Nó không phải là một rõ ràng.

Vấn đề lớn hơn là mã như vậy đã biến mất với nó. Hoặc là do may mắn, không suy nghĩ quá nhiều về vấn đề sơn thường xuyên hoặc bằng cách nghĩ rằng hủy bỏ các ứng dụng khi nó bế tắc và khởi động lại nó một lần một ngày là chấp nhận được. Bởi vì các lập trình viên không có hy vọng thực sự phát hiện ra vấn đề mà không cần chẩn đoán.

Microsoft quan tâm rất nhiều đến tính năng tương thích ngược, ngay cả khi nó bị lỗi. Việc sửa chữa là tuyệt vời, mặc dù đôi khi nó là sai (Hiển thị (chủ sở hữu) được kiểm tra khi nó không nên). Và đôi khi nhìn ra để kiểm tra xem khi nào mã trong khuôn khổ vi phạm quy tắc. Điều này xảy ra khi phụ thuộc luồng là gián tiếp. Các trường hợp phổ biến nhất đang cập nhật nguồn dữ liệu của điều khiển ràng buộc dữ liệu trong luồng công nhân (unbind first!) Và sử dụng điều khiển lắng nghe sự kiện SystemEvents.UserPreferenceChanged (không tạo giao diện người dùng trên chuỗi thứ hai!)


Để tham khảo, các mã có liên quan có mặt trong constructor tĩnh của lớp điều khiển:

static Control() 
{ 
    //... 
    checkForIllegalCrossThreadCalls = Debugger.IsAttached; 
    //... 
} 
Các vấn đề liên quan