2010-09-24 23 views
5

Xin chào Ở biểu mẫu của tôi, tôi tạo TFrame khi chạy. Tại khung này, tôi tạo ra chủ đề nền với thực hiện các lệnh trong vòng lặp vô tận. Nhưng khi tôi phá hủy khung này, tôi nên tiêu diệt chủ đề này. Tôi thửHủy chỉ tiêu chính xác

thread.Suspend; 
thread.Terminate; 
FreeAndNil(thread); 

nhưng nhận AV và ThreadError. Làm thế nào tôi nên tiêu diệt luồng?

+0

thể trùng lặp của [Miễn phí một TThread tự động hoặc bằng tay] (http://stackoverflow.com/questions/3557105/free-a-tthread-either-automatically-or-manually) –

+3

Đừng trì hoãn quyết chủ đề. Phương thức chấm dứt chỉ đặt thuộc tính Terminated thành true và phương thức Execute của bạn có trách nhiệm chấm dứt luồng. Nếu nó bị đình chỉ, nó sẽ không có cơ hội chấm dứt. – jachguate

+0

Một vấn đề khác với mã ở trên, là nó có khả năng giải phóng luồng trước khi nó có thay đổi để chấm dứt cách thông thường. –

Trả lời

13

Bạn phải đảm bảo rằng chuỗi thoát khỏi phương thức thực thi của nó để chấm dứt nó đúng cách.

Mã có thể là một cái gì đó như thế này:

procedure TThread.Execute; 
begin 
    while not Self.Terminated do 
    begin 
    //do something 
    end; 
end; 

Gọi này khi Bạn muốn tiêu diệt chủ đề:

thread.Terminate; 
thread.WaitFor; 
FreeAndNil(thread); 
+0

Không cần thiết phải gọi 'Terminate' và' WaitFor' từ bên ngoài, vì destructor thread sẽ tự làm điều đó. Nó có thể là cần thiết mặc dù để gọi nó từ các destructor bị ghi đè, trước khi bất kỳ trường nào được giải phóng, để đảm bảo rằng các trường này không còn được sử dụng từ luồng. – mghie

4

Đủ để làm thread.Terminate. Nhưng có thể bạn sẽ muốn đặt thread.FreeOnTerminate := true khi được tạo.

Tất nhiên, trong vòng lặp chặt của chủ đề của bạn (nghĩa là, trong Execute), bạn cần kiểm tra xem chuỗi đã được yêu cầu chấm dứt chưa (kiểm tra thuộc tính Terminated). Nếu bạn thấy rằng chuỗi đã được yêu cầu chấm dứt, chỉ cần thoát khỏi vòng lặp và thoát khỏi Execute.

+0

thread.Terminate chỉ đặt thuộc tính FTerminated thành True. Nó không phá hủy sợi chỉ. – Linas

+2

Tôi biết. Nhưng mỗi thread phải kiểm tra điều đó trong phương thức Execute của nó.Tôi cho rằng OP đang làm điều này. –

4

Bạn không bao giờ nên gọi đình chỉ trên một TThread nó không an toàn để làm như vậy và sơ yếu lý lịch chỉ nên được sử dụng để bắt đầu một chuỗi đã được tạo.

Trong Delphi 2010, việc tạm ngưng và tiếp tục bị khấu hao và phương pháp bắt đầu được giới thiệu để củng cố điều này.

Để được giải thích đầy đủ hơn, hãy xem điều này thread tại diễn đàn Codegears.

đã nói rằng có 2 cách tôi sẽ chấm dứt và miễn phí một tthread.

1: Tôi đặt FreeOnTerminate khi chuỗi được tạo nên tôi chỉ cần gọi.

Thread.Terminate; 

2: Giải phóng chuỗi một cách rõ ràng, vì tôi cần đọc kết quả từ tài sản công cộng trước khi chuỗi được giải phóng và sau khi kết thúc.

Thread.Terminate; 
Thread.WaitFor; 
//Do somthing like read a public property from thread object 
if Thread <> nil then FreeAndNil(Thread); 

Trong chính thực hiện vòng lặp nó có thể là một ý tưởng tốt để đặt một số xử lý ngoại lệ trong. Hoặc bạn có thể để lại thắc mắc tại sao các chủ đề dường như chấm dứt tự của nó. Điều này có thể gây ra AV nếu chuỗi được đặt thành FreeOnTerminate và nó đã được giải phóng khi bạn cố giải phóng nó.

procedure TThread.Execute; 
begin 
    while not Terminated do 
    begin 
    try 
     //do something 
    except 
     on E:Exception do 
     //handle the exception 
    end; 
    end; 
end; 
Các vấn đề liên quan