My goal is speed up process of send emails, because send only with 1 email account will delay a long time when have a big list of recipients.
Then i have a txt file with several email account each line is equal to this:
Then i want create a quantity of threads equals to number of lines of this txt file ( with clarity if is greater than it, will cause errors :-) ) passing each info between "|" delimiter as parameter to each thread.
All emails recipients will be present in a unique Memo
(line by line) and my app not must send same message to the same recipient once already sent.
I have a example about how create several threads, but i not know how pass these parameters to each thread created:
type
TMyThread = class(TThread)
private
protected
procedure Execute; override;
public
constructor Create;
end;
constructor TMyThread.Create;
begin
inherited True;
FreeOnTerminate := True;
Priority := tpNormal;
end;
//=================================================================
var
I: Integer;
MyThreadList: array [0..2] of TMyThread; // creates two threads
begin
for I := 0 to High(MyThreadList) do
begin
MyThreadList[I] := TMyThread.Create(True);
MyThreadList[I].FreeOnTerminate := True;
MyThreadList[I].Priority := tpNormal;
MyThreadList[I].Resume;
end;
end;
Also if exist some better idea to speed up process of send emails using only 1 email account, will be welcome.
To pass parameters to a thread, simply add input parameters to TMyThread
's constructor. Either as individual string
values (Host
, Port
, Username
, Password
, etc), or as a TStringList
, or a record
, whatever you are comfortable passing. The constructor can then save the data in members of the class for Execute()
to use as needed. In this regard, threads don't work any differently than any other class. Only that Execute()
runs in a different context than the constructor does.
I suggest you use a thread pool with a couple of thread-safe lists. One list of SMTP providers, and one list of recipients. Create a thread pool with only as many threads as there are installed CPUs (if more than the number of recipients being sent to).
Each thread can then do the following:
extract a recipient from the recipients list. Or a handful, since a single email can be sent to multiple recipients at a time, especially if multiple recipients are on the same email domain. If no recipient(s) are available, exit.
then, extract an idle SMTP provider from the providers list. If not already connected to it, connect and login as needed.
then, send an email to the recipient(s).
then, put the SMTP provider back in the providers list (or, leave it in the list the whole time and just mark it as idle). Leave the connection open, so another thread (or even the same thread) can use the same connection on its next iteration.
Go back to #1.
Once all threads have finished, cleanup as needed.
Now, with that said, note that SMTP providers thwart spammers in many ways, including:
whitelisting only known good senders, like other legitimate SMTP providers. You can send emails using your own email provider's SMTP server, but you can't always send emails to a recipient's SMTP server directly (if they are on a different email provider than you).
limiting how many simultaneous TCP connections you can open to them
limiting how many emails you can send at a time
limiting how many emails you can send within a given time period
limiting how often you can send emails.
No amount of threading will get you past these kind of limitations. If anything, you usually have to pay extra to remove them.
The best way to handle this kind of situation is to setup an online mailing list (such as with Yahoo Groups), and then you can send 1 email to 1 address and let the mailing list provider distribute the email to subscribed members for you.