具有多个电子邮件帐户的多线程发送到收件人列表?
Multithread with several email account sending to a list of recipients?
我的目标是加快发送电子邮件的速度,因为当收件人列表很大时,仅使用 1 个电子邮件帐户发送会延迟很长时间。
然后我有一个包含多个电子邮件帐户的 txt 文件,每一行等于:
- smtp.company.fr|marketing@company.fr|emailpass |587
然后我想创建一个线程数量等于这个 txt 文件的行数(清楚如果大于它,将导致错误:-))在“|”之间传递每个信息定界符作为每个线程的参数。
所有电子邮件收件人都将以唯一 Memo
(逐行)的形式出现,并且我的应用程序不必在发送后向同一收件人发送相同的邮件。
我有一个关于如何创建多个线程的示例,但我不知道如何将这些参数传递给创建的每个线程:
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;
此外,如果有一些更好的想法来加快仅使用 1 个电子邮件帐户发送电子邮件的过程,我们将受到欢迎。
要将参数传递给线程,只需将输入参数添加到 TMyThread
的构造函数。作为单独的 string
值(Host
、Port
、Username
、Password
等),或作为 TStringList
,或 record
,随随便便就过去了。然后构造函数可以将数据保存在 class 的成员中,供 Execute()
需要时使用。在这方面,线程的工作方式与其他线程没有任何不同 class。只有 Execute()
在与构造函数不同的上下文中运行。
我建议您使用带有几个线程安全列表的线程池。一份 SMTP 提供商列表和一份收件人列表。创建一个线程池,其线程数与已安装的 CPU 数相同(如果多于发送到的收件人数)。
然后每个线程可以执行以下操作:
从收件人列表中提取收件人。或者少数,因为一封电子邮件可以一次发送给多个收件人,尤其是当多个收件人在同一个电子邮件域中时。如果没有可用的收件人,则退出。
然后,从提供商列表中提取一个空闲的 SMTP 提供商。如果尚未连接到它,请根据需要连接并登录。
然后,向收件人发送电子邮件。
然后,将 SMTP 提供程序放回提供程序列表中(或者,将其始终留在列表中,并将其标记为空闲)。让连接保持打开状态,这样另一个线程(甚至是同一个线程)可以在其下一次迭代中使用同一个连接。
返回#1。
所有线程完成后,根据需要进行清理。
话虽如此,请注意 SMTP 提供商以多种方式阻止垃圾邮件发送者,包括:
仅将已知的良好发件人列入白名单,就像其他合法的 SMTP 提供商一样。您可以使用自己的电子邮件提供商的 SMTP 服务器发送电子邮件,但您不能总是将电子邮件直接发送到收件人的 SMTP 服务器(如果他们与您使用不同的电子邮件提供商)。
限制您可以同时打开的 TCP 连接数
限制您一次可以发送多少封电子邮件
限制您在给定时间段内可以发送的电子邮件数量
限制发送电子邮件的频率。
再多的线程也无法克服这些限制。如果有的话,您通常需要支付额外费用才能删除它们。
处理这种情况的最好方法是设置一个在线邮件列表(例如使用 Yahoo Groups),然后您可以将 1 封电子邮件发送到 1 个地址,让邮件列表提供商将邮件分发给订阅者会员给你。
我的目标是加快发送电子邮件的速度,因为当收件人列表很大时,仅使用 1 个电子邮件帐户发送会延迟很长时间。
然后我有一个包含多个电子邮件帐户的 txt 文件,每一行等于:
- smtp.company.fr|marketing@company.fr|emailpass |587
然后我想创建一个线程数量等于这个 txt 文件的行数(清楚如果大于它,将导致错误:-))在“|”之间传递每个信息定界符作为每个线程的参数。
所有电子邮件收件人都将以唯一 Memo
(逐行)的形式出现,并且我的应用程序不必在发送后向同一收件人发送相同的邮件。
我有一个关于如何创建多个线程的示例,但我不知道如何将这些参数传递给创建的每个线程:
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;
此外,如果有一些更好的想法来加快仅使用 1 个电子邮件帐户发送电子邮件的过程,我们将受到欢迎。
要将参数传递给线程,只需将输入参数添加到 TMyThread
的构造函数。作为单独的 string
值(Host
、Port
、Username
、Password
等),或作为 TStringList
,或 record
,随随便便就过去了。然后构造函数可以将数据保存在 class 的成员中,供 Execute()
需要时使用。在这方面,线程的工作方式与其他线程没有任何不同 class。只有 Execute()
在与构造函数不同的上下文中运行。
我建议您使用带有几个线程安全列表的线程池。一份 SMTP 提供商列表和一份收件人列表。创建一个线程池,其线程数与已安装的 CPU 数相同(如果多于发送到的收件人数)。
然后每个线程可以执行以下操作:
从收件人列表中提取收件人。或者少数,因为一封电子邮件可以一次发送给多个收件人,尤其是当多个收件人在同一个电子邮件域中时。如果没有可用的收件人,则退出。
然后,从提供商列表中提取一个空闲的 SMTP 提供商。如果尚未连接到它,请根据需要连接并登录。
然后,向收件人发送电子邮件。
然后,将 SMTP 提供程序放回提供程序列表中(或者,将其始终留在列表中,并将其标记为空闲)。让连接保持打开状态,这样另一个线程(甚至是同一个线程)可以在其下一次迭代中使用同一个连接。
返回#1。
所有线程完成后,根据需要进行清理。
话虽如此,请注意 SMTP 提供商以多种方式阻止垃圾邮件发送者,包括:
仅将已知的良好发件人列入白名单,就像其他合法的 SMTP 提供商一样。您可以使用自己的电子邮件提供商的 SMTP 服务器发送电子邮件,但您不能总是将电子邮件直接发送到收件人的 SMTP 服务器(如果他们与您使用不同的电子邮件提供商)。
限制您可以同时打开的 TCP 连接数
限制您一次可以发送多少封电子邮件
限制您在给定时间段内可以发送的电子邮件数量
限制发送电子邮件的频率。
再多的线程也无法克服这些限制。如果有的话,您通常需要支付额外费用才能删除它们。
处理这种情况的最好方法是设置一个在线邮件列表(例如使用 Yahoo Groups),然后您可以将 1 封电子邮件发送到 1 个地址,让邮件列表提供商将邮件分发给订阅者会员给你。