Ignore:
Timestamp:
Nov 16, 2011, 10:07:51 AM (13 years ago)
Author:
george
Message:
  • Added: Exception handling in TThreadPool. If exception occurs in one of pool threads this will raise exception in main thread from RunInThread method is executed. This require special handling on the side of main thread.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Common/UResetableThread.pas

    r295 r298  
    2323  private
    2424    FLock: TCriticalSection;
     25    FOnException: TExceptionEvent;
    2526    FOnFinished: TNotifyEvent;
    2627    FStartEvent: TEvent;
     
    4243    property StopPending: Boolean read FStopPending;
    4344    property Running: Boolean read GetRunning;
     45    property OnException: TExceptionEvent read FOnException
     46      write FOnException;
    4447  end;
    4548
     
    4851  TThreadPool = class(TThreadedPool)
    4952  private
     53    FOnException: TExceptionEvent;
    5054    procedure MethodFinish(Sender: TObject);
     55    procedure ThreadException(Sender: TObject; E: Exception);
    5156  protected
    5257    function NewItemObject: TObject; override;
    5358  public
     59    LastExceptionClass: TClass;
     60    LastExceptionMessage: string;
     61    procedure CheckException;
    5462    procedure WaitForEmpty;
     63    procedure Clear;
    5564    procedure RunInThread(AMethod: TMethodCall);
    5665    constructor Create; override;
    5766    destructor Destroy; override;
     67    property OnException: TExceptionEvent read FOnException
     68      write FOnException;
    5869  end;
    5970
     
    193204          try
    194205            FLock.Release;
    195             Method;
    196             if Assigned(FOnFinished) then
    197               FOnFinished(Parent);
     206            try
     207              try
     208                Method;
     209              finally
     210                if Assigned(FOnFinished) then
     211                  FOnFinished(Parent);
     212              end;
     213            except
     214              on E: Exception do
     215                if Assigned(FOnException) then
     216                  FOnException(Self, E);
     217            end;
    198218          finally
    199219            FLock.Acquire;
     
    219239end;
    220240
     241procedure TThreadPool.ThreadException(Sender: TObject; E: Exception);
     242begin
     243  LastExceptionClass := E.ClassType;
     244  LastExceptionMessage := E.Message;
     245end;
     246
     247procedure TThreadPool.CheckException;
     248begin
     249  if Assigned(LastExceptionClass) then
     250    raise Exception.Create(LastExceptionMessage);
     251end;
     252
    221253function TThreadPool.NewItemObject: TObject;
    222254begin
    223255  Result := TResetableThread.Create;
     256  TResetableThread(Result).OnException := ThreadException;
    224257end;
    225258
    226259procedure TThreadPool.WaitForEmpty;
    227260begin
    228   while UsedCount > 0 do
     261  while UsedCount > 0 do begin
    229262    Sleep(1);
     263  end;
     264end;
     265
     266procedure TThreadPool.Clear;
     267begin
     268  TotalCount := 0;
     269  LastExceptionClass := nil;
     270  LastExceptionMessage := '';
    230271end;
    231272
    232273procedure TThreadPool.RunInThread(AMethod: TMethodCall);
    233274begin
     275  CheckException;
    234276  with TResetableThread(Acquire) do begin
    235277    Method := AMethod;
Note: See TracChangeset for help on using the changeset viewer.