2010-03-22 31 views
5

Tôi có một chương trình Delphi đơn giản mà tôi đang làm việc, trong đó tôi đang cố gắng sử dụng luồng để tách chức năng của chương trình khỏi giao diện đồ họa của nó, và giữ giao diện GUI trong thời gian dài hơn nhiệm vụ, vv Về cơ bản, tôi có một 'điều khiển' TThread, và một 'xem' TForm. Khung nhìn biết xử lý của bộ điều khiển, mà nó sử dụng để gửi thông báo điều khiển qua PostThreadMessage. Tôi đã không có vấn đề gì trong quá khứ bằng cách sử dụng loại mô hình này cho các biểu mẫu không phải là biểu mẫu chính, nhưng vì một số lý do, khi tôi cố gắng sử dụng mô hình này cho biểu mẫu chính, vòng lặp thông điệp của chuỗi chỉ thoát.Thông điệp chủ đề Vòng treo trong Delphi

Đây là mã của tôi cho các vòng lặp đề thông điệp:

procedure TController.Execute; 
var 
    Msg : TMsg; 
begin 
    while not Terminated do begin 
    if (Integer(GetMessage(Msg, hwnd(0), 0, 0)) = -1) then begin 
     Synchronize(Terminate); 
    end; 

    TranslateMessage(Msg); 
    DispatchMessage(Msg); 

    case Msg.message of 
     // ...call different methods based on message 
    end; 
    end; 
end; 

Để thiết lập bộ điều khiển, tôi làm điều này:

Controller := TController.Create(true); // Create suspended 
Controller.FreeOnTerminate := True; 
Controller.Resume; 

Đối xử lý tin nhắn dạng chính, tôi đã cố gắng sử dụng cả Application.Run và vòng lặp sau (ngay sau Controller.Resume)

while not Application.Terminated do begin 
    Application.ProcessMessages; 
end; 

Tôi đã chạy bị kẹt ở đây - mọi trợ giúp sẽ được đánh giá cao.

+1

Chào mừng bạn đến với Stack Overflow, erikjw! Tôi hy vọng bạn tìm thấy một câu trả lời tốt. Ghi chú nhanh, mặc dù. Nó làm cho mã của bạn khó đọc hơn khi bạn đặt một 'bắt đầu' trên cùng một dòng với' do' hoặc 'then' trước nó. Đó được coi là phong cách tốt trong C, nhưng trong Delphi hầu hết chúng ta thích đặt nó trên dòng riêng của mình vì vậy chúng tôi có thể xếp hàng 'bắt đầu' và' kết' cặp trực quan. –

+0

Cảm ơn tất cả các câu trả lời cho đến nay. Tôi đã thử từng cách riêng biệt, cũng như một số kết hợp khác nhau và tôi vẫn gặp sự cố. Khi tôi thực hiện một debug, và bước qua đoạn mã trong 'TController.Execute', ngay khi tôi bước qua' GetMessage', cho dù tôi truyền cái gì đi nữa, nó không liên tục đi qua vòng lặp. Nó không thực thi bất kỳ câu lệnh nào sau vòng lặp, nó chỉ dừng lại một cách không giải thích được. Và điều thậm chí còn khó hiểu hơn là tôi không thấy dấu hiệu nào cho thấy chính sợi chỉ đã chết. –

+0

Bạn đã thử xóa 'Synchronize()' chưa? Nếu không có vòng lặp tin nhắn nào chạy, nó có thể bị lỗi. Ngoài ra, bạn đang sử dụng phiên bản Delphi nào? – Nat

Trả lời

3

Tôi đã kiểm tra mã của bạn về cơ bản như hiện tại và hoạt động tốt. Hãy thử thêm một cuộc gọi vào GetLastError sau khi GetMessage trả về -1 để xem vấn đề là gì.

Nó không hoàn toàn rõ ràng từ mã cho dù bạn đang tạo cửa sổ trong chuỗi bộ điều khiển, nhưng nếu không, tôi khuyên bạn nên chuyển -1 thay vì 0 làm HWND thành GetMessage và xóa các cuộc gọi TranslateMessage/DispatchMessage, kể từ khi tuyên bố trường hợp theo sau họ nên xử lý bất kỳ tin nhắn bạn nhận được.

Ngoài ra, bạn không cần phải thực hiện "Đồng bộ hóa (Chấm dứt)" do lỗi. Chấm dứt chỉ đặt boolean "Chấm dứt" thành true, vì vậy bạn không cần phải đồng bộ hóa nó, và bạn có thể dễ dàng sử dụng "Break" để thoát ra khỏi vòng lặp với cùng một hiệu ứng.

0

Trường hợp "kết thúc" cho vòng lặp while? Tôi nghĩ bạn đã bỏ lỡ và kết thúc. Vì vậy, có thể (tùy thuộc vào mã thực tế), bạn bị kẹt trong vòng lặp while not Terminated do không ngừng trên một tuyên bố đơn lẻ.

+0

Thats xấu của tôi, tôi sẽ sửa chữa điều đó trong câu hỏi - vòng lặp bao gồm khá nhiều chức năng toàn bộ. –

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