Page 1 of 1

TBackgroundWorker - small enhancement

PostPosted: June 20th, 2011, 6:39 am
by Ian Hinson
I use TBackgroundWorker occasionally and found a small annoyance with it is the need to set up data, either global or with form scope, for TBackgroundWorker.OnWork to work with before calling BackgroundWorker1.Execute
This means for example defining private data members in TMyForm specifically for use by TBackgroundWorker, and initialising them before calling its Execute method, as no way has been provided to "pass data" to TBackgroundWorker.

However I made a simple change to the TBackgroundWorker class (in my copy of its source) that now enables me to pass it specific data to work on. All I did was this:
Code: Select all
TBackgroundWorker = class(TComponent)
private
  ....
  fUserObject: TObject;  // new field
public
  ....
  property UserObject: TObject read fUserObject write fUserObject;
published
   ....
end;

The UserObject property can be initialised like this:
Code: Select all
procedure TForm1.Button1Click(Sender: TObject)
var
  myobj: TMyObject;
begin
  myobj := TMyObject.Create;
  ... // initialise myobj fields here
  BackgroundWorker1.UserObject := myobj;
  BackgroundWorker1.Execute;
end;

Then, in the OnWork event, user data can be retrieved like this:
Code: Select all
procedure TForm1.BackgroundWorker1Work(Worker: TBackgroundWorker);
var
  myobj: TMyObject;
begin
  myobj := Worker.UserObject as TMyObject;
  .... // do something with it
end;

Optionally, the user data can finally be freed:
Code: Select all
procedure TForm1.BackgroundWorker1WorkComplete(Worker: TBackgroundWorker; Cancelled: Boolean);
begin
  Worker.UserObject.Free;
end;

For your info,

Ian.

Re: TBackgroundWorker - small enhancement

PostPosted: June 21st, 2011, 4:37 pm
by Kambiz
The Tag property can safely store an integer, a pointer, or an object.

Code: Select all
procedure TForm1.Button1Click(Sender: TObject)
var
  myobj: TMyObject;
begin
  myobj := TMyObject.Create;
  ... // initialise myobj fields here
  BackgroundWorker1.Tag := Integer(myobj);
  BackgroundWorker1.Execute;
end;

procedure TForm1.BackgroundWorker1Work(Worker: TBackgroundWorker);
var
  myobj: TMyObject;
begin
  myobj := TMyObject(Worker.Tag);
  .... // do something with it
end;

procedure TForm1.BackgroundWorker1WorkComplete(Worker: TBackgroundWorker; Cancelled: Boolean);
begin
  TMyObject(Worker.Tag).Free;
end;