Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TStringList in thread

Status
Not open for further replies.

safra

Technical User
Jan 24, 2001
319
NL
Hi,

I am trying to pass a stringlist to a thread. Not much success so far. In brief this is what I have:

Code:
unit MailThread;

interface
Uses Classes, SysUtils, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP, IdMessage,dialogs;

Type
  TMailThread = Class( TThread )

    Private
      FslImages: TStringList;
    Protected
      Procedure Execute; Override;
    Public
      Property slImages: TStringList read FslImages write FslImages;
    End;

implementation

{ TMailThread }
procedure TMailThread.Execute;
begin
  // inline images
  for i := 0 to FslImages.count - 1 do
   begin
    // ... 
   end;
end;

end.

Looking at the error message I quess the problem has to do with the fact that the stringlist FslImages has not been created yet.

However I cannot figure out how to pass a stringlist from form1 to stringlist FslImages in the thread?

Any ideas?

Thanks,
Raoul
 
Preview: if you are doing something like that:

Code:
// In main
List := TListString.Create;
MailThread := TmailThread.Create(False); // create and run
MailThread.slImages := List;

Yes, you have a good chance of running your thread upon a non created object and crashing your program right on start. If the machine is fast enough the OS can (and will) run the thread (the Execute procedure) before the main code getting a chance to set the list pointer.

You have a lot of options to solve the issue, and the better two are:

1) Start the thread stopped, load the property and run the thread.

Code:
// In main
List := TListString.Create;
MailThread.Create(True); // create suspended!
MailTrhread.slImages := List;
MailThread.Resume; // run the thread

2) Pass the List in the constructor.

Code:
constructor MailThread.Create(List : TStringList);
begin
  FslImages := List; // before creation!
  inherited Create(False); // create and run
end;

// In main
List := TListString.Create;
MailThread := TmailThread.Create(List);

Anyway, do NOT access the list from the main thread after your worker thread (MailThread) is running without due synchronization (critical sections) or you'll be in deep trouble.

If your problem is not solved this way, please post some more code and elaborate further.

buho (A).
 
Thanks buho!

Actually I am doing what you suggested in your first option:

Code:
 NewThread := TMailThread.Create(True);
 NewThread.FreeOnTerminate := True;
 NewThread.Body := sw;
 NewThread.Subject := SendMail.Subject.Text;
 NewThread.Priority := SendMail.Priority; 
 NewThread.slImages := slImages;
 NewThread.Resume;

And, I don't no why, but now I do not get error.

But slImages in MailThread remains empty while I am sure slImages on the main form is not empty.

Any ideas why?
 
I think it's better to copy the stringlist to your thread, not just referencing it.

should be done like this :

NewThread.slImages.Items.Assign(slImages);

this makes a copy of your stringlist, not a reference to it...



 
Yes, this part is working now, thanks!

But

NewThread.slImages.Items.Assign(slImages);

raises errors.

I did somthing like this,

NewThread.slImages.Assign(slImages);
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top