ho scritto un piccolo programma per mostrare come fermare correttamente un'attività in background. Speriamo che sia più chiaro.
il contenuto del file ThreadConsoleApplication.dpr:
program ThreadConsoleApplication;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
Classes;
type
{ **
* Classe TQueueReaderTestApplication
* }
TThreadConsoleApplication = class(TThread)
public
procedure Execute; override;
constructor Create; virtual;
destructor Destroy; override;
class function getInstance: TThreadConsoleApplication;
end;
function TThreadConsoleApplication_consoleCtrlHandler(dwCtrlType: DWORD): BOOL;
stdcall; forward;
{ **
* Classe TQueueReaderTestApplication
* }
constructor TThreadConsoleApplication.Create;
begin
inherited Create(True { CreateSuspended });
Windows.setConsoleCtrlHandler(@TThreadConsoleApplication_consoleCtrlHandler,
True { add });
end;
var
threadConsoleApplicationInstance: TThreadConsoleApplication = nil;
destructor TThreadConsoleApplication.Destroy;
begin
threadConsoleApplicationInstance := nil;
inherited;
end;
procedure TThreadConsoleApplication.Execute;
begin
System.Writeln('[TThreadConsoleApplication.Execute] begin');
try
while not Terminated do
begin
System.Writeln('[TThreadConsoleApplication.Execute] running ...');
Windows.Sleep(1000 { dwMilliseconds });
end;
finally
System.Writeln('[TThreadConsoleApplication.Execute] end');
end;
end;
class function TThreadConsoleApplication.getInstance: TThreadConsoleApplication;
begin
if nil = threadConsoleApplicationInstance then
begin
threadConsoleApplicationInstance := TThreadConsoleApplication.Create;
end;
Result := threadConsoleApplicationInstance;
end;
function TThreadConsoleApplication_consoleCtrlHandler(dwCtrlType: DWORD): BOOL;
begin
Result := False;
if Windows.CTRL_C_EVENT = dwCtrlType then
begin
TThreadConsoleApplication.getInstance.Terminate;
Result := True;
end;
end;
var
thread: TThread;
begin
System.Writeln('[program] begin');
try
thread := nil;
try
thread := TThreadConsoleApplication.getInstance;
thread.Resume;
System.Writeln('[program] press a CTRL+C to stop running');
thread.WaitFor;
finally
thread.Free;
end;
System.Writeln('[program] end');
except
on E: Exception do
begin
System.Writeln(System.ErrOutput, '[program] end with error');
System.Writeln(System.ErrOutput, E.ClassName, ': ', E.Message);
end;
end;
System.Writeln('[program] press a key to quit');
System.Readln;
end.
fonte
2012-04-18 08:36:14
Ok, questo dimostra come posso disabilitare Ctrl + C - vorrei chiarire la mia domanda: come faccio a eseguire un arresto applicazione pulito dopo il rilevamento di Ctrl + C? – mjn
Oh, capisco. Se intrappoli il Ctrl + C, come il mio esempio, puoi impostare una sorta di 'flag' e terminare * normalmente * ogni volta che vuoi. –
Ho appena ricordato la "pausa: = falso;" che ho usato per inserire i miei programmi Turbo Pascal per disabilitare Ctrl-Break. Ah, nostalgia ... –