2014-09-22 1 views
0

이것은 OmniThread 라이브러리와 별도의 스레드로 구현 한 스톱워치의 샘플 코드입니다.폼이 닫힐 때 OmniThread 작업을 종료하고 종료하지 않습니까?

이것은 내 질문입니다. 폼을 닫을 때 작업을 종료하고 종료해야합니까? 아니면 폼이 닫힐 때 자동으로 닫힙니 까?

uses 
    System.SysUtils, System.Classes, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, 

    OtlComm, OtlTask, OtlTaskControl, OtlEventMonitor; 

type 
    TForm1 = class(TForm) 
    OTLMonitor: TOmniEventMonitor; 
    btnStartClock: TButton; 
    btnStopClock: TButton; 
    procedure btnStartClockClick(Sender: TObject); 
    procedure btnStopClockClick(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    procedure OTLMonitorTaskMessage(const task: IOmniTaskControl; const msg: TOmniMessage); 
    procedure OTLMonitorTaskTerminated(const task: IOmniTaskControl); 
    private 
    { Private-Deklarationen } 
    FClockTask: IOmniTaskControl; 
    public 
    { Public-Deklarationen } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ Place a TOmniEventMonitor component on the form, 
    name it OTLMonitor, 
    implement the OnTaskTerminated event-handler: OTLMonitorTaskTerminated 
    and implement the OnTaskmessage event-handler: OTLMonitorTaskMessage } 

var 
    StopMessage: string; 

procedure ShowElapsedSeconds(const ATask: IOmniTask); 
var 
    ElapsedSeconds: Integer; 
begin 
    ElapsedSeconds := 0; 
    while not ATask.Terminated do 
    begin 
    // stop after 10 seconds: 
    if ElapsedSeconds >= 10 then BREAK; 

    Inc(ElapsedSeconds); 
    ATask.Comm.Send(ElapsedSeconds); 
    Sleep(1000); 
    end; 
end; 

procedure TForm1.OTLMonitorTaskMessage(const task: IOmniTaskControl; const msg: TOmniMessage); 
begin 
    // show elapsed seconds: 
    Self.Caption := IntToStr(msg.MsgID); 
end; 

procedure TForm1.OTLMonitorTaskTerminated(const task: IOmniTaskControl); 
begin 
    FClockTask := nil; 
    Self.Caption := StopMessage; 
end; 

procedure TForm1.btnStartClockClick(Sender: TObject); 
begin 
    if not Assigned(FClockTask) then // prevent multiple clock-tasks 
    begin 
    StopMessage := 'Automatically stopped after 10 seconds'; 
    FClockTask := CreateTask(ShowElapsedSeconds, 'ShowElapsedSeconds').MonitorWith(OTLMonitor).Run; 
    end 
    else 
    begin 
    MessageDlg('Clock is already running!', mtInformation, [mbOK], 0); 
    { Nice: The clock continues to run even while this message dialog is displayed! } 
    end; 
end; 

procedure TForm1.btnStopClockClick(Sender: TObject); 
begin 
    if Assigned(FClockTask) then 
    begin 
    StopMessage := 'Stopped by the user'; 
    FClockTask.Terminate; 
    FClockTask := nil; 
    end 
    else 
    MessageDlg('Clock is not running!', mtInformation, [mbOK], 0); 
end; 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    if Assigned(FClockTask) then 
    begin 
    { Do I need to terminate and nil the clock-task here? 
     Or will it be destroyed autmatically when the form closes? } 
    end; 
end; 
+0

입니다. 'OTLMonitorTaskTerminated'는 절대로 참조되지 않습니다. 'FClockTask'는 소유 객체가 파괴 될 때 스코프를 벗어납니다. 다른 변수와 같습니다. –

+0

@DavidHeffernan'OTLMonitorTaskTerminated'는 폼에 배치 된'OTLMonitor' 컴포넌트의 이벤트 핸들러입니다. 작업이 종료되면 (10 초 후 또는 사용자가 자동으로) 트리거됩니다. 나는 여기에 아무것도 잘못 본다. "결코 언급하지 않음"이란 무엇을 의미합니까? – user1580348

+0

글쎄 .dfm 파일을 볼 수 없습니다. 그래서 제가 여기에서 본 것에서, 그 방법은 결코 언급되지 않았습니다. –

답변

1

프리 모즈 Gabrijelčič, "OmniThreadLibrary와 병렬 프로그래밍"의 저자의 글 :

는 "우리는 또한 배경 동안 'X'버튼을 클릭 하여 프로그램을 종료 사용자의 가능성을 처리해야 스캐너가 활성화됩니다. 우리는 OnFormCloseQuery 이벤트를 잡아 종료 작업을 알려야합니다.

procedure TfrmBackgroundFileSearchDemo.FormCloseQuery(Sender: TObject; 
var CanClose: boolean); 
begin 
    if assigned(FScanTask) then 
    begin 
    FScanTask.Terminate; 
    FScanTask := nil; 
    CanClose := true; 
    end; 
end;" 

이 책의 판매는 http://leanpub.com/omnithreadlibrary

관련 문제