infoimg: Array[0..19] of TImage;
Last time i was told, that a thread can access the LCL elements via Synchronize. My program does that now. What do you suggest, how should i load the images from a separate thread?
true synchronize executes the code in the context of the main application thread and that is safe.To load the images in a thread I usually create the timage control in the thread load the image and pass the image back to the main thread ready for use. The main thread will assign it to its place.
Do not reuse TImage from a thread you are setting your self for failure.
Edit : The above statement is a bit vague and I feel I have to elaborate a bit more.
It is ok to use a TImage control from a thread as long as you make sure that when used in the thread the main thread can not access it in any way. To use your example
If we assume that your code does not have any other reference for the TImage control in infoimg[Self.CEI] then the following is enough to make it thread safe.
procedure TImageThread.LoadAPicture;
var
vImage:TImage;
begin
lock;
try
vImage.Picture.LoadFromStream(Self.Buffer);
finally
unlock;
end;
end;
that of course assumes that every time you want to access what is in infoimg[Self.CEI] you call lock. You can make things a bit less waiting by doing something along the lines of
procedure TImageThread.LoadAPicture;
var
vImage:TImage;
begin
lock;
vimage := infoimg[Self.CEI];
infoimg[Self.CEI] := nil;
unlock;
vImage.Picture.LoadFromStream(Self.Buffer);
lock;
infoimg[Self.CEI] := vImage;
unlock.
end;
In which case you allow your other code to check for nil before use and skip if its nil.
The moment you assign infoimg[Self.CEI] to a button or any other variable that might access it asynchrously with out calling your lock you cant trust that the data are properly protected from corruption and your only choice is something like.
procedure TImageThread.LoadAPicture;
var
vImage:TImage;
begin
vImage := TImage.Create(nil);//infoimg[Self.CEI];
vImage.Picture.LoadFromStream(Self.Buffer);
lock;
try
infoimg[Self.CEI].Free;
infoimg[Self.CEI] := vImage;
finally
unlock;
end;
end;
Oh if it is not apparent so far the lock protects what happens in your array or cell (depends on how you have it set up) not what happens with the data of timage it self so even if you have call lock if the image is on a form or other control that paints it on the screen then you are not protected from corruption when calling loadfromstream from a thread.