Asynkron kørsel af Tnotifyevent
Jeg er generelt ikke stor tilhænger af tråde, men er røget ud i en situation, hvor jeg har nogle opgaver i mit program, som egner sig til at køre i baggrunden. Jeg vil gerne kunne kalde disse opgaver med en simpel TnotifyEvent ala:procedure TForm1.DoSomething(Sender : Tobject);
begin
//
end;
det ville være perfekt, hvis denne kunne kaldes som:
dmAsync.Execute(DoSomething, Sender);
Som starter et baggrundsjob og returnerer umiddelbart efter.
Fejlbehandling skal klares efterfølgende.
Til formålet har jeg lavet denne kode, som desværre giver en fejlmeddelelse:
Threaderror: Handlen er ikke gyldig(6)
når modulet skabes og Execute(SampleMethod, nil) kaldes.
Er der nogen der har et bud på hvordan det skal laves?
unit udmAsyncCall;
interface
uses
SysUtils, Classes, ExtCtrls;
type
TdmAsync = class(TDataModule)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure DataModuleCreate(Sender: TObject);
procedure Execute(Method : tNotifyEvent; Sender : tObject);
procedure SampleMethod(sender : tobject);
private
{ Private declarations }
ThreadList : tlist;
public
{ Public declarations }
end;
var
dmAsync: TdmAsync;
implementation
{$R *.dfm}
type
tMythread = class (TThread)
constructor Create(aMethod : Tnotifyevent; aSender : tobject);
private
method : tNotifyevent;
sender : tobject;
protected
procedure Execute; override;
end;
{ tMythread }
constructor tMythread.Create(amethod: Tnotifyevent; aSender: tobject);
begin
priority := tpLower;
method := amethod;
sender := aSender;
end;
procedure tMythread.Execute;
begin
inherited;
method(sender);
end;
procedure TdmAsync.Execute(method: tNotifyEvent; sender: tObject);
begin
tmythread.create(method, sender);
end;
procedure TdmAsync.DataModuleCreate(Sender: TObject);
begin
threadlist := tlist.create;
execute(samplemethod, nil);
end;
procedure TdmAsync.Timer1Timer(Sender: TObject);
var i : integer;
t : tMythread;
begin
// Fejlbehandling, skal udbygges...
for i := 0 to threadlist.count-1 do
if tmythread(threadlist[i]).Terminated then
begin
t := threadlist[i];
threadlist.Delete(i);
t.Free;
exit;
end;
end;
procedure TdmAsync.SampleMethod(sender: tobject);
begin
sleep(1000);
end;
end.