.net 使用任务并行库发送邮件时引发错误

.net 使用任务并行库发送邮件时引发错误,.net,task-parallel-library,c#-5.0,.net,Task Parallel Library,C# 5.0,代码:- List tasks=newlist(); foreach(arr中的var项)//arr包含1000多个mailid { tasks.Add(Task.Factory.StartNew(()=> { 使用(MailMessage msg=new MailMessage()) { msg=getmsg();//此处的p-shadow代码没有erorr SmtpClient smtp=新SmtpClient(); smtp.Host=smtpServer; smtp.Port=smtpP

代码:-

List tasks=newlist();
foreach(arr中的var项)//arr包含1000多个mailid
{
tasks.Add(Task.Factory.StartNew(()=>
{
使用(MailMessage msg=new MailMessage())
{
msg=getmsg();//此处的p-shadow代码没有erorr
SmtpClient smtp=新SmtpClient();
smtp.Host=smtpServer;
smtp.Port=smtpPort;
smtp.EnableSsl=isSmtpSsl!=0?真:假;
smtp.Credentials=新的网络凭据(smtpUName、smtpPass);
smtp.Timeout=int.MaxValue;
smtp.Send(msg);//---抛出错误。。。。
//用于插入发送邮件的数据库的sql代码
}
},TaskCreationOptions.longrung));
}
Task.WaitAll(tasks.ToArray());
错误-“发送邮件失败。”


内部错误-“无法从传输连接读取数据:net\u io\u connectionclosed。”

正如Jim提到的,您可能遇到了限制/拒绝情况。依我看,如果1)使用单个SmtpClient而不是N个SmtpClient(因此单个客户端可以在必要时进行内部序列化),以及2)使用内置异步调用()而不是StartNew并调用同步版本,您可能会更成功

比如:

List<Task> tasks = new List<Task>();
foreach (var item in arr)//arr contains 1000+ mailids
            {
                tasks.Add(Task.Factory.StartNew(() =>
                {
                    using (MailMessage msg = new MailMessage())
                        {
                            msg=getmsg();//p-shadow code no erorr here
                            SmtpClient smtp = new SmtpClient();
                            smtp.Host = smtpServer;
                            smtp.Port = smtpPort;
                            smtp.EnableSsl = isSmtpSsl != 0 ? true : false;
                            smtp.Credentials = new NetworkCredential(smtpUName,smtpPass);
                            smtp.Timeout = int.MaxValue;
                            smtp.Send(msg);//---throws error....
                            //sql code to insert db that mail is send
                        }
                }, TaskCreationOptions.LongRunning));
            }
            Task.WaitAll(tasks.ToArray<Task>());

不过,我不确定这是否真的会有多大帮助——如果仍然失败,您可能只需要执行一个长时间运行的任务,连续发送电子邮件。

关于“net\u io\u connectionclosed”异常,请查看此链接,因为它可能会为您指明关闭连接的正确方向。可能是身份验证问题、防火墙等

请在下面找到我在您的情况下使用的代码,而不是生成1000个不太有效的任务


可能是因为您打开了太多与SMTP服务器的连接,或者是因为连接速度太快而导致您无法正常工作?如果你每秒做一次会发生什么。。。或者每五秒钟一个?我不认为
SmtpClient
(或服务器)支持同时多个连接到同一台服务器。想想你要求它做什么:你要求多个
SmtpClient
对象连接到同一台服务器并发送电子邮件
SmtpClient
将重复使用到同一服务器的连接,因此您可能处于竞争状态。您是否尝试过使用
SendAsync
而不是使用
Task
?至少,我希望您会使用一个
SmtpClient
object,我上周有同样的项目要做。我一到pc就会发布一些代码。P.S使用并行for循环,而不是创建多个任务。如果正在进行电子邮件传输,并且您再次调用SendAsync或Send,您将收到InvalidOperationException。取自“”@DNNDev.co.za-我的代码段调用的方法是SendMailAsync,而不是Send或sendsync。当然,它可能会以同样的方式运行,文档只是没有更新,但那部分文档并没有说它会失败:)抱歉,我没有读到你的代码在做什么,还以为它在调用SendAsync。谢谢你的解决方案。我想问一下你是如何决定const int_clientcount=15的?clientcount是否取决于运行的硬件,或者每台机器的smtp数量是否受到.net/IIST的限制?这仅适用于我的环境。取决于每个环境和SMTP服务器的设置。每个IP可能只允许5个连接。也许可以使用配置设置,以便您可以根据环境进行调整。@RyanGunn在您设置SMTPClient的地方,我需要将其更改为适用于不同的主机。因为我会使用不同的主机smtp凭据发送电子邮件。因此,我必须为不同的主机启动15个客户端。你能给我举个例子说明我怎么做吗
var messages = ... // get collection of MailMessage instances
var smtpClient = new SmtpClient { ... }; // construct a single SmtpClient
var tasks = messages.Select(smtpClient.SendMailAsync).ToArray();
Task.WaitAll(tasks);