Autor Beitrag
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 29.08.10 00:48 
Hier noch eine WorkerThread Implementierung. Sie funktioniert über APC (Asynchronous Procedure Calls) und sollte effizient sein.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
unit WorkerThread;

interface

uses Classes, SysUtils;

type
  TAPCMethod = procedure of objectstdcall;

  TWorkerThread = class;

  TErrorEvent = procedure(Sender: TWorkerThread; E: Exception);

  TWorkerThread = class
  private
    FThread: TThread;
    FOnError: TErrorEvent;
    function GetHandle: THandle;
  public
    property OnError: TErrorEvent read FOnError write FOnError;
    property ThreadHandle: THandle read GetHandle;
    procedure Queue(Method: TAPCMethod);
    constructor Create;
    destructor Destroy; override;
  end;

implementation

uses Windows;

type
  TThreadWorker = class(TThread)
  protected
    FThread: TWorkerThread;
    procedure Void; stdcall;
  public
    constructor Create(AThread: TWorkerThread);
    procedure QueueAPC(Method: TAPCMethod);
    procedure Execute; override;
    destructor Destroy; override;
  end;

procedure TThreadWorker.Execute;
begin
  repeat
    try
      SleepEx(INFINITE, True);
    except
      on E: Exception do
        if Assigned(FThread.FOnError) then
          FThread.FOnError(FThread, E);
    end;
  until Terminated;
end;

constructor TThreadWorker.Create(AThread: TWorkerThread);
begin
  FThread := AThread;
  inherited Create(False);
end;

destructor TThreadWorker.Destroy;
begin
  if (ThreadID <> 0and not Finished and not ExternalThread then
  begin
    Terminate;
    QueueAPC(Void);
  end;
  inherited;
end;

procedure TThreadWorker.Void;
begin
end;

procedure TThreadWorker.QueueAPC(Method: TAPCMethod);
begin
  if not QueueUserAPC(TMethod(Method).Code, Handle, Cardinal(TMethod(Method).Data)) then
    RaiseLastOSError;
end;

{ TWorkerThread }

constructor TWorkerThread.Create;
begin
  FThread := TThreadWorker.Create(Self);
end;

destructor TWorkerThread.Destroy;
begin
  FThread.Free;
  inherited;
end;

function TWorkerThread.GetHandle: THandle;
begin
  Result := FThread.Handle;
end;

procedure TWorkerThread.Queue(Method: TAPCMethod);
begin
  TThreadWorker(FThread).QueueAPC(Method);
end;

end.

Für diesen Beitrag haben gedankt: BenBE