Trong MSDN, mô tả của phương thức Thread.Abort () cho biết: "Việc gọi phương thức này thường kết thúc luồng."
Tại sao không LUÔN?
Trong trường hợp nào nó không kết thúc luồng?
Có khả năng nào khác để kết thúc chủ đề không?
Trong MSDN, mô tả của phương thức Thread.Abort () cho biết: "Việc gọi phương thức này thường kết thúc luồng."
Tại sao không LUÔN?
Trong trường hợp nào nó không kết thúc luồng?
Có khả năng nào khác để kết thúc chủ đề không?
Câu trả lời:
Thread.Abort()
tiêm a ThreadAbortException
vào chủ đề. Chủ đề có thể hủy yêu cầu bằng cách gọi điện Thread.ResetAbort()
. Ngoài ra, có một số phần mã nhất định, chẳng hạn như finally
khối sẽ thực thi trước khi xử lý ngoại lệ. Nếu vì lý do nào đó mà luồng bị kẹt trong một khối như vậy thì ngoại lệ sẽ không bao giờ được nâng lên trên luồng.
Vì người gọi có rất ít quyền kiểm soát trạng thái của luồng khi gọi Abort()
, nên thường không nên làm như vậy. Thay vào đó, hãy chuyển một tin nhắn đến chuỗi yêu cầu chấm dứt.
Trong trường hợp nào nó không kết thúc luồng?
Câu hỏi này là một bản sao.
Có gì sai khi sử dụng Thread.Abort ()
Có bất kỳ khả năng nào khác để kết thúc chủ đề không?
Đúng. Vấn đề của bạn là bạn không bao giờ nên bắt đầu một chuỗi mà bạn không thể nói một cách lịch sự để dừng lại, và nó dừng lại kịp thời. Nếu bạn đang ở trong tình huống mà bạn phải bắt đầu một chuỗi có thể (1) khó dừng, (2) lỗi, hoặc tệ nhất là (3) thù địch với người dùng, thì điều cần làm là làm một quy trình mới, bắt đầu tiểu trình trong quy trình mới, rồi kết thúc quy trình khi bạn muốn tiểu trình ngừng hoạt động. Điều duy nhất có thể đảm bảo chấm dứt an toàn luồng bất hợp tác là hệ điều hành gỡ bỏ toàn bộ quy trình của nó.
Xem câu trả lời quá dài của tôi cho câu hỏi này để biết thêm chi tiết:
Sử dụng câu lệnh khóa trong vòng lặp trong C #
Phần có liên quan là phần ở cuối nơi tôi thảo luận về những điều cần cân nhắc liên quan đến việc bạn nên đợi bao lâu để một chuỗi tự kết thúc trước khi bạn hủy bỏ nó.
Tại sao không LUÔN? Trong trường hợp nào nó không kết thúc chủ đề?
Đối với người mới bắt đầu, một chuỗi có thể bắt một ThreadAbortException
và hủy bỏ kết thúc của chính nó. Hoặc nó có thể thực hiện một phép tính mất vĩnh viễn trong khi bạn đang cố gắng hủy bỏ nó. Do đó, thời gian chạy không thể đảm bảo rằng luồng sẽ luôn kết thúc sau khi bạn yêu cầu nó.
ThreadAbortException
có thêm:
Khi một lệnh gọi đến phương thức Abort để hủy một luồng, thời gian chạy ngôn ngữ chung sẽ ném ra một ThreadAbortException. ThreadAbortException là một ngoại lệ đặc biệt có thể được bắt, nhưng nó sẽ tự động được nâng lên một lần nữa ở cuối khối bắt. Khi ngoại lệ này được nâng lên, thời gian chạy thực thi tất cả các khối cuối cùng trước khi kết thúc luồng. Vì luồng có thể thực hiện tính toán không giới hạn trong các khối cuối cùng hoặc lệnh gọi
Thread.ResetAbort()
hủy bỏ, không có gì đảm bảo rằng luồng sẽ kết thúc.
Bạn không cần phải Abort()
xâu chuỗi thủ công. CLR sẽ thực hiện tất cả công việc khó khăn cho bạn nếu bạn chỉ để phương thức trong luồng trả về; điều đó sẽ kết thúc luồng bình thường.
Điều gì sẽ xảy ra nếu một luồng đang giữ khóa và bị hủy / hủy? Nguồn lực vẫn bị kẹt
Nó hoạt động tốt khi một luồng gọi tự hủy bỏ mà không phải bởi luồng khác. Hủy bỏ, buộc chấm dứt chuỗi bị ảnh hưởng ngay cả khi nó chưa hoàn thành nhiệm vụ và không tạo cơ hội cho việc dọn dẹp tài nguyên
tham khảo MSDN
Tôi dường như không thể hủy bỏ một chuỗi bị mắc kẹt trong một vòng lặp:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
Tuy nhiên, tôi có thể hủy chuỗi nếu ngủ trong vòng lặp:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
ThreadAborts sẽ không xảy ra bên trong khối cuối cùng hoặc giữa BeginCriticalRegion và EndCriticalRegion
Vì bạn có thể bắt ThreadAbortException
và gọi Thread.ResetAbort
bên trong trình xử lý.
OT: Để biết toàn diện, ngôn ngữ bất khả tri, hữu ích đáng ngờ và hài hước đáng kinh ngạc về đồng thời, hãy xem Verity Stob !
Tôi đã gặp trường hợp luồng quá bận để nghe lệnh gọi Abort (), điều này thường dẫn đến một ThreadAbortingException được ném vào mã của tôi.