2009-06-10 26 views
7

Tôi có một chuỗi thoát ra và cố gắng tạo kết nối. Trong chuỗi, tôi thực hiện cuộc gọi đến thư viện của bên thứ ba. Đôi khi, cuộc gọi này bị treo và không bao giờ trở lại. Trên chuỗi giao diện người dùng, tôi muốn có thể hủy kết nối bằng cách hủy bỏ chuỗi, thao tác này sẽ hủy bỏ cuộc gọi bị treo tới thư viện của bên thứ ba.Làm cách nào để xử lý một chuỗi có cuộc gọi bị treo?

Tôi đã gọi Thread.Abort, nhưng bây giờ đã đọc Thread.Abort chỉ hoạt động khi kiểm soát trả về mã được quản lý. Tôi đã quan sát thấy rằng điều này là đúng, bởi vì các chủ đề không bao giờ hủy bỏ, và tôi đã ngồi trên Thread.Join trong mười phút ngay bây giờ. Tôi nên làm gì với chuỗi treo này? Tôi có nên chỉ cần tham khảo và di chuyển không? Tôi muốn càng sạch càng tốt -

Trả lời

3

Chức năng này trong thư viện của bên thứ ba của bạn không có một thời gian chờ hoặc hủy chức năng? Nếu vậy, đó là thiết kế khá kém. Sẽ không có bất kỳ giải pháp nào tuyệt vời ở đây, hãy liên kết ...

Thật không may, không có cách nào bạn có được xung quanh nó, thiếu sử dụng API Win32 để xóa chuỗi thủ công, chắc chắn là không sẽ được sạch sẽ. Tuy nhiên, nếu thư viện bên thứ ba này không cung cấp cho bạn bất kỳ tùy chọn nào khác, thì đó có thể là điều cần làm. Chức năng TerminateThread là những gì bạn sẽ muốn sử dụng, nhưng hãy quan sát cảnh báo! Để có được ID thread chuyển đến hàm này, bạn phải sử dụng một cuộc gọi API Win32 khác (lớp Thread không hiển thị trực tiếp). Cách tiếp cận ở đây sẽ là đặt giá trị của biến lớp biến động thành kết quả của GetCurrentThreadId khi bắt đầu phương thức chuỗi được quản lý, sau đó sử dụng ID luồng này sau để chấm dứt chuỗi.

4

Ngẫu nhiên suy nghĩ: Tôi tự hỏi bạn có thể viết một bản lắp ráp thứ hai như một giao diện điều khiển nhỏ mà thực hiện liên lạc này ... khởi chạy nó với Process.Start và nắm bắt kết quả hoặc thông qua hệ thống tệp hoặc bằng cách chặn stdout. Sau đó, nếu nó treo, bạn có thể giết chết quá trình.

Hơi khắc nghiệt, có thể - và rõ ràng là nó có chi phí sinh sản quá trình - nhưng ít nhất cũng có thể giết nó.

+4

"Cất cánh và nuke trang web từ quỹ đạo - đó là cách duy nhất để chắc chắn". Thật vậy, bạn là chính xác; đây là cách an toàn duy nhất được bảo đảm để chấm dứt mã không đúng. Thread.Abort không được bảo đảm để thực sự hủy bỏ các thread misbehaving; một chủ đề thực sự bị xáo trộn có thể chiếm đoạt việc hủy bỏ. Ngay cả khi lấy xuống một appdomain không nhất thiết phải làm những gì bạn muốn. Nếu bạn hoàn toàn, tích cực phải giết mã hành vi xấu sau đó bạn cần phải cô lập nó với một quá trình giết người. –

+0

Cảm ơn Ripley ... Ý tôi là ... Eric ;-p (Tôi đã trả lời của Hudson, nhưng sau đó tôi phải sử dụng các công cụ điều tiết trên chính mình ...) –

1

Chủ đề được quản lý không thể dừng trực tiếp chuỗi gốc. Vì vậy, nếu các cuộc gọi bị chặn trong mã nguồn gốc thì tốt nhất bạn có thể làm là có kiểm tra thread quản lý sau đó chấm dứt khi nó trả về. Nếu nó không bao giờ trở lại, có thể có một phiên bản của cuộc gọi với một timemout?

Nếu không được, giết chết các chủ đề (thông qua win32) không phải là thường là một ý tưởng tốt ...

+0

cuộc gọi không bao giờ trở lại, đó là lý do tại sao tôi có để kết thúc sợi chỉ một cách giả tạo. – MedicineMan

2

Không chắc chắn nếu điều này sẽ làm điều đó hoặc có thể chấp nhận được, nhưng nó đáng để bắn.

[DllImport("kernel32.dll")] 
private static extern bool TerminateThread (Int32 id, Int32 dwexit); 

Từ documentation

TerminateThread là một chức năng nguy hiểm mà chỉ nên được sử dụng trong các trường hợp cực đoan nhất. Bạn nên gọi TerminateThread chỉ khi bạn biết chính xác những gì mà thread đích đang làm, và bạn kiểm soát tất cả các mã mà thread đích có thể có thể đang chạy tại thời điểm kết thúc. Ví dụ: TerminateThread có thể dẫn đến các sự cố sau:

  • Nếu chuỗi đích sở hữu phần quan trọng, phần quan trọng sẽ không được giải phóng.
  • Nếu chuỗi mục tiêu cấp phát bộ nhớ từ heap, khóa heap sẽ không được giải phóng.
  • Nếu chuỗi đích đang thực hiện một số cuộc gọi kernel32 nhất định khi kết thúc, trạng thái kernel32 cho quy trình của luồng có thể không nhất quán.
  • Nếu chuỗi mục tiêu đang thao tác trạng thái toàn cục của một DLL được chia sẻ, trạng thái của DLL có thể bị hủy, ảnh hưởng đến những người dùng DLL khác.
-1

Không phải là một giải pháp tốt để chờ đợi trên một chuỗi (bằng bất kỳ ngôn ngữ nào) vô thời hạn, đặc biệt nếu bạn đang thực hiện cuộc gọi bên ngoài. Luôn sử dụng kết nối với thời gian chờ hoặc khóa xoay giám sát trạng thái của biến nguyên tử được chia sẻ cho đến khi thay đổi hoặc bạn đạt đến thời gian chờ. Tôi không phải là một C# guy, nhưng đây là tất cả các thực hành đồng thời âm thanh.

+0

thậm chí bạn đã đọc câu hỏi –

+0

Chắc chắn đã làm - cảm ơn mặc dù. – Gandalf

Các vấn đề liên quan