Hier noch eine WorkerThread Implementierung. Sie funktioniert über APC (Asynchronous Procedure Calls) und sollte effizient sein.
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 object; stdcall;
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 <> 0) and 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;
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. |