2009-10-12 22 views
14

Sự khác biệt giữa Thraed.Abort() và Thread.Interrupt() là gì. Làm thế nào tôi có thể gọi chúng trong một Thread Manner.It sẽ là hữu ích, nếu ví dụ đơn giản được cung cấp.Sự khác biệt giữa Hủy bỏ và Ngắt trong Chủ đề trong .NET

+0

Bạn có thể cung cấp ví dụ về những gì bạn đang cố gắng làm không? Hình thức câu hỏi hiện tại của bạn có mâu thuẫn. – Gary

Trả lời

23

Trước hết, cả hai cấu trúc này đều là cấu trúc đồng bộ hóa chuỗi tốt.

Đầu tiên, Thread.Abort nói "Tôi không quan tâm những gì bạn đang làm, chỉ cần ngừng làm và để mọi thứ như bây giờ". Về cơ bản nó là cách lập trình để nói "Này, đánh bại nó". Nếu chuỗi của bạn đang mở các tệp, các tệp đó sẽ được mở cho đến khi thu thập rác xung quanh để hoàn thành các đối tượng của bạn.

Thread.Abort chỉ nên được sử dụng, và thậm chí sau đó có thể không, trong trường hợp miền ứng dụng mà luồng đang chạy bên trong đang bị rách, tốt nhất là chỉ khi quá trình đang bị chấm dứt.

Thứ hai, Thread.Interrupt là một con thú khá lạ. Về cơ bản nó nói "Tôi không quan tâm những gì bạn đang chờ đợi, ngừng chờ đợi nó". Điều kỳ lạ ở đây là nếu thread không chờ đợi bất cứ điều gì, nó thay vì "Tôi không quan tâm những gì bạn sẽ chờ đợi tiếp theo, nhưng khi bạn làm thế, hãy ngừng chờ nó ngay lập tức".

Cả hai dấu hiệu này là dấu hiệu cho thấy bạn đang áp đặt ý chí của mình lên một chủ đề không được thiết kế để nói những điều như vậy.

Để hủy bỏ chủ đề đúng cách, chuỗi nên định kỳ kiểm tra một số loại cờ, có thể là biến Boolean biến động đơn giản hoặc đối tượng sự kiện. Nếu lá cờ nói "Bây giờ bạn nên chấm dứt", chủ đề phải chấm dứt chính nó bằng cách trở về từ các phương pháp theo một cách có trật tự.

Để đánh thức một chủ đề đúng cách, một luồng phải ở vị trí cần chờ đối tượng đồng bộ hóa, bao gồm đối tượng "vui lòng ngừng chờ" mà nó cũng đợi. Vì vậy, về cơ bản nó sẽ cho một trong hai đối tượng nó cần trở thành tín hiệu, hoặc "xin vui lòng ngừng chờ đợi" đối tượng trở thành tín hiệu, xác định cái nào đã làm, và làm điều đúng.

Vì vậy, thay vì Thread.Abort và Thread.Interrupt, bạn nên viết bài bằng cách sử dụng đối tượng đồng bộ bình thường, như các sự kiện, mutexes, Cột vv

Đối với lý do tương tự, Thread.SuspendThread.Resume nên để một mình và chúng cũng đã lỗi thời trong các phiên bản sau của .NET.

10

Trừ khi bạn đang gọi điện thoại Abort hoặc Interrupt trên thread hiện đang thực hiện (như ASP.NET nào để chấm dứt một yêu cầu đột ngột, ví dụ) về cơ bản bạn không thể gọi cho họ một cách thread-safe.

Sử dụng WaitHandle hoặc Monitor.Wait/Pulse để đợi theo cách dễ dàng. Bạn chỉ nên hủy bỏ các chủ đề khác nếu bạn đang rách ứng dụng, về cơ bản - nếu không bạn có thể kết thúc ở trạng thái không xác định.

Xem my article on graceful thread termination để biết ví dụ về cách thực hiện điều này một cách độc đáo.

+0

Bài viết hay về Jon.By the Way, nơi tôi có thể tìm thấy Webcast của bạn? – user186973

+0

@threadinglearner: Bạn có nghĩa là webcast nào? –

+0

Bất cứ điều gì về C# – user186973

2

Thread.Abort() đặt ra một ThreadAbortException trên chuỗi đích. Đó là ý định nói chung để buộc các chủ đề để chấm dứt. Nó không phải là một thực hành được đề nghị để ngăn chặn xử lý của một sợi.

Thread.Interrupt() ngắt một luồng nằm trong trạng thái WaitSleepJoin - về cơ bản là chặn một tài nguyên như WaitHandle. Điều này cho phép người gọi bỏ chặn chuỗi.

Không thực sự là "an toàn chỉ" - theo nghĩa là chúng đặc biệt nhằm ảnh hưởng đến hành vi của các chuỗi theo cách khó dự đoán.

Thường được khuyến nghị sử dụng các đối tượng đồng bộ hóa (như WaitHandles hoặc Semaphores) để cho phép các luồng đồng bộ hóa an toàn với nhau.

1

Sự khác biệt giữa Abort và Interrupt là trong khi cả hai sẽ ném một ngoại lệ (ThreadAbortException và ThreadInterruptException), gọi Abort sẽ trả về ngoại lệ ở cuối khối catch và chắc chắn sẽ kết thúc chuỗi đang chạy của bạn.

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