2010-09-27 27 views
8

Tôi có một câu hỏi khác! Hãy nhìn vào ví dụ này:Làm thế nào để vượt qua ngoại lệ từ một chủ đề khác (người gọi) thread trong Delphi?

// There is a class with some method: 
type 
    TMyClass = class 
    public 
    procedure Proc1; 
    end; 

    // There is a some thread class: 
    TMyThread = class(TThread) 
    protected 
    procedure Execute; override; 
    end; 

procedure TMyClass.Proc1; 
begin 
    // this method is just calling another thread: 
    with TMyThread.Create(True) do 
    begin 
    FreeOnTerminate := True; 
    Resume; 
    end; 
    // + there are some more actions 
end; 

procedure TMyThread.Execute; 
begin 
    // in this example this thread just throws exception: 
    raise Exception.Create('Some exception'); 
end; 

Tất cả những gì tôi muốn - là để huy động ngoại lệ trong TMyClass.Proc1 và ném nó lên như thế này:

var 
    myObject: TMyClass; 
begin 
    myObject := TMyClass.Create; 
    try 
    myObject.Proc1; // launch and watch what happenings 
    except 
    on E: Exception do 
     WriteErrorLog(E.Message); 
    end; 
    FreeAndNil(myObject); 
end; 

xin vui lòng cho tôi biết làm thế nào tôi có thể làm một cái gì đó như thế này? Rất cám ơn!

oh! một điều nữa - im mã hóa trên Delphi 5 vì vậy tôi không có "FatalException" tài sản của TThread hoặc một cái gì đó về ..

+2

Bạn cần chấp nhận câu trả lời hoặc nếu không có câu trả lời nào đủ để bạn chỉ ra rằng ví dụ: bằng cách bình luận – Remko

Trả lời

2

Tóm lại, bạn không thể làm điều này theo cách bạn muốn.

Bạn cần sao chép đối tượng ngoại lệ, chuyển bản sao sang chủ đề khác của bạn (ví dụ: sử dụng phương thức Đồng bộ hóa hoặc sử dụng kỹ thuật đồng bộ hóa khác) và nâng cao đối tượng ngoại lệ đó.

17

Bạn có thể sử dụng AcquireExceptionObject():

AcquireExceptionObject trả về một con trỏ đến đối tượng ngoại lệ hiện tại và ngăn chặn các đối tượng ngoại lệ khỏi bị deallocated khi thoát xử lý ngoại lệ hiện hành.

Sau đó, bạn có thể gửi con trỏ đến một chuỗi khác và nếu bạn nâng nó lên đó, nó sẽ được giải phóng cho bạn, nếu không bạn phải gọi ReleaseExceptionObject() để giải phóng nó.

+5

+1 cho 'AcquireExceptionObject()'. Vì nó không có sẵn trong Delphi 5, bạn nên sao chép thực hiện cho Delphi 5 từ AsyncCalls.pas, có thể được tải xuống từ http://andy.jgknet.de/blog/?page_id=100. Đơn vị này cũng sẽ chỉ cho bạn cách sử dụng mã theo đúng cách. – mghie

+0

Chủ đề AcquireExceptionObject có an toàn không? Ít nhất tôi nhận được kết quả lạ khi sử dụng nó trong nhiều chủ đề tức là chặn xảy ra? –

+0

Trường hợp ngoại lệ là một trường hợp của một đối tượng vì vậy tôi cho rằng đó là chủ đề an toàn (được hỗ trợ bởi thực tế là các tài liệu không đề cập đến nó) – Remko

0

Tốt nhất bạn đặt bẫy ngoại lệ trong vòng lặp thực thi trên chuỗi và viết thuộc tính thư và tên lớp vào trường chuỗi riêng tư. Điều này sau đó có thể được công khai bằng cách sử dụng một tài sản với các phần quan trọng trong getters và setters, đảm bảo truy cập là threadsafe. Bây giờ tất cả những gì bạn phải làm là chuyển vào luồng một quá trình để xử lý ngoại lệ và gọi nó với một đồng bộ hóa. Tôi sẽ đăng một số mã ví dụ khi tôi truy cập vào máy tính của mình, khi tôi đang sử dụng iPhone của mình tại thời điểm

-1

Tôi thực hiện loại điều này nguyên bản trong khung đa luồng của mình (http://www.csinnovations.com /framework_overview.htm).

+0

Trên thực tế, tôi chỉ nhận thấy bạn vẫn đang sử dụng Delphi 5 vì vậy nó sẽ không được giúp đỡ nhiều. – Misha

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