Changeset 245 for Common/UThreading.pas


Ignore:
Timestamp:
May 23, 2011, 10:59:04 AM (13 years ago)
Author:
george
Message:
  • Added: Thread safe global thread list management.
  • Added: DeleteFiles routine.
  • Modified: GetUserNameEx use dynamic loaded library.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Common/UThreading.pas

    r230 r245  
    66
    77uses
    8   Classes, SysUtils, Forms, Contnrs;
     8  Classes, SysUtils, Forms, Contnrs, SyncObjs;
    99
    1010type
    11 
     11  TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;
    1212  TMethodCall = procedure of object;
    13 
    14   { TTermThread }
    15 
    16   TTermThread = class(TThread)
    17     Finished: Boolean;
    18     Method: TMethodCall;
    19     procedure Execute; override;
    20   end;
    2113
    2214  { TListedThread }
     
    2820    destructor Destroy; override;
    2921    procedure Sleep(Delay: Integer);
     22    property Terminated;
     23  end;
     24
     25  { TTermThread }
     26
     27  TTermThread = class(TListedThread)
     28  private
     29  public
     30    Finished: Boolean;
     31    Method: TMethodCall;
     32    procedure Execute; override;
    3033  end;
    3134
    3235var
    33   ThreadList: TObjectList; // TListedThread
     36  ThreadList: TObjectList; // TList<TListedThread>
     37  ThreadListLock: TCriticalSection;
     38  OnException: TExceptionEvent;
    3439
    3540procedure RunInThread(Method: TMethodCall);
    3641procedure Synchronize(Method: TMethodCall);
     42
     43resourcestring
     44  SCurrentThreadNotFound = 'Current thread ID %d not found in list.';
    3745
    3846
     
    4957    Thread.Method := Method;
    5058    while not Thread.Finished do begin
    51       Application.ProcessMessages;
     59      if MainThreadID = ThreadID then Application.ProcessMessages;
    5260      Sleep(1);
    5361    end;
     
    7078      Thread := TListedThread(ThreadList[I]);
    7179      TThread.Synchronize(Thread, Method);
    72     end else raise Exception.Create(Format('Current thread ID %d not found in list.', [ThreadID]));
     80    end else raise Exception.Create(Format(SCurrentThreadNotFound, [ThreadID]));
    7381  end;
    7482end;
     
    8088begin
    8189  inherited;
    82   ThreadList.Add(Self);
     90  try
     91    ThreadListLock.Acquire;
     92    ThreadList.Add(Self);
     93  finally
     94    ThreadListLock.Release;
     95  end;
    8396end;
    8497
    8598destructor TListedThread.Destroy;
    8699begin
    87   ThreadList.Delete(ThreadList.IndexOf(Self));
     100  if not Suspended then
     101  begin
     102    Terminate;
     103    WaitFor;
     104  end;
     105  try
     106    ThreadListLock.Acquire;
     107    ThreadList.Delete(ThreadList.IndexOf(Self));
     108  finally
     109    ThreadListLock.Release;
     110  end;
    88111  inherited Destroy;
    89112end;
     
    106129procedure TTermThread.Execute;
    107130begin
    108   Method;
    109   Finished := True;
     131  try
     132    Method;
     133    Finished := True;
     134  except
     135    on E: Exception do
     136      if Assigned(OnException) then
     137        OnException(Self, E);
     138  end;
    110139end;
    111140
    112141initialization
    113142
     143ThreadListLock := TCriticalSection.Create;
    114144ThreadList := TObjectList.Create;
    115145ThreadList.OwnsObjects := False;
     
    118148
    119149ThreadList.Free;
     150ThreadListLock.Free;
    120151
    121152end.
Note: See TracChangeset for help on using the changeset viewer.