C#smtp异步发送未发送
我正在尝试通过sendasync发送电子邮件。问题是它似乎没有进入sendcompleted事件处理程序。我在那里添加了一个断点,但它从未触发。程序只是在我的信号灯处等待。有什么想法吗?该程序是一个windows窗体应用程序C#smtp异步发送未发送,c#,smtp,sendasync,C#,Smtp,Sendasync,我正在尝试通过sendasync发送电子邮件。问题是它似乎没有进入sendcompleted事件处理程序。我在那里添加了一个断点,但它从未触发。程序只是在我的信号灯处等待。有什么想法吗?该程序是一个windows窗体应用程序 if (send) { print("Starting to send mail to " + Globalcls.projects[i].name); mailSendSe
if (send)
{
print("Starting to send mail to " + Globalcls.projects[i].name);
mailSendSemaphore = new Semaphore(0, 1);
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(Globalcls.projects[i].email);
msg.From = new MailAddress(Globalcls.settings.server_email);
msg.Subject = "Data";
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = "Please see attached data";
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
foreach (string fileName in files)
{
msg.Attachments.Add(new System.Net.Mail.Attachment(fileName));
}
SmtpClient client = new SmtpClient();
client.Credentials = new System.Net.NetworkCredential(Globalcls.settings.username, Globalcls.settings.password);
client.Port = Convert.ToInt32(Globalcls.settings.portS);//or use 587
client.Host = "smtp.xdsl.co.za";
client.SendCompleted += new SendCompletedEventHandler(MailSendCallback);
client.SendAsync(msg,null);
mailSendSemaphore.WaitOne();
// if (Globalcls.error_message != "")
// throw Exception
//client.Dispose();
print("email sent to " + Globalcls.projects[i].name);
client.Dispose();
mailSendSemaphore.Dispose();
msg.Dispose();
}
//Array.ForEach(Directory.GetFiles(GlobalClass.projects[i].foldero), delegate(string path) { File.Delete(path); });
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(Globalcls.projects[i].foldero);
foreach (System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
这是我的OnSendHandler
private static void MailSendCallback(object sender, AsyncCompletedEventArgs arg)
{
// oncomllete event for async send.
if (arg.Error != null)
Globalcls.error_message = arg.Error.ToString();
// Release the main thread
mailSendSemaphore.Release();
}
编辑
我想使用sendasync的原因是sendasync显然在等待文件上传完成。当前的问题是,有时附件太大,以至于上传所需时间超过超时时间。我可以延长超时时间,但我不知道应该延长多长时间。大多数电子邮件很容易达到3mb。我们的adsl线路并不总是最稳定的
等待异步发送的原因是每个客户端不能有多个发送。这就是为什么我要等它结束
我的问题更多地与超时有关。我想要一个超时,只有当smtp和smtp客户端之间没有通信时才会超时
编辑2
这就是我的代码最初的样子。我想尽量避免那个巨大的超时。多线程只会使gui不挂起
if (send)
{
print("Starting to send mail to " + Globalcls.projects[i].name);
// mailSendSemaphore = new Semaphore(0, 1);
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(Globalcls.projects[i].email);
msg.From = new MailAddress(Globalcls.settings.server_email);
msg.Subject = "Data";
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = "Please see attached data";
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
foreach (string fileName in files)
{
msg.Attachments.Add(new System.Net.Mail.Attachment(fileName));
}
SmtpClient client = new SmtpClient();
client.Credentials = new System.Net.NetworkCredential(Globalcls.settings.username, Globalcls.settings.password);
client.Port = Convert.ToInt32(Globalcls.settings.portS);//or use 587
// client.Host = "127.0.0.1";
client.Host = "smtp.xdsl.co.za";
client.Timeout = 400000;
client.Send(msg);
/* client.SendCompleted += new SendCompletedEventHandler(MailSendCallback);
client.SendAsync(msg,null);
mailSendSemaphore.WaitOne();*/
// if (Globalcls.error_message != "")
// throw Exception
print("email sent to " + Globalcls.projects[i].name);
client.Dispose();
//mailSendSemaphore.Dispose();
msg.Dispose();
}
//Array.ForEach(Directory.GetFiles(GlobalClass.projects[i].foldero), delegate(string path) { File.Delete(path); });
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(Globalcls.projects[i].foldero);
foreach (System.IO.FileInfo file in directory.GetFiles()) file.Delete();
foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
catch (Exception ex)
{
print("Error with " + Globalcls.projects[i].name);
print(ex.ToString());
timer1.Enabled = false;
timer1.Stop();
btn_start.Enabled = true;
string contents = "There was an error in sending mail to " + Globalcls.projects[i].name;
string heading = " Anxo error";
string subject = "Anxo error";
errormail(heading, subject, contents, ex.ToString(), Globalcls.projects[i].sos);
result = false;
}
安装IIS/SmtpService并让它处理上载。i、 e.使用
SmtpClient
将电子邮件发送到localhost:25
=本地IIS
我想这样做可以得到更为固体的溶液。因为IIS将继续尝试在出现故障时上载消息
更新
大概是这样的:
public class EmailSender
{
ConcurrentQueue<MailMessage> _queue = new ConcurrentQueue<MailMessage>();
private Thread _worker;
ManualResetEvent _trigger = new ManualResetEvent(false);
private bool _shutdown;
public EmailSender()
{
_worker = new Thread(SendEmails);
_worker.Start();
}
public void Enqueue(MailMessage message)
{
_queue.Enqueue(message);
_trigger.Set();
}
public void Shutdown()
{
_shutdown = true;
_trigger.Set();
_worker.Join();
}
private void SendEmails(object state)
{
while (true)
{
_trigger.WaitOne(Timeout.Infinite);
if (_shutdown)
return; // you might want to send all emails instead.
MailMessage msg;
if (!_queue.TryDequeue(out msg))
{
_trigger.Reset();
continue;
}
SendEmail(msg);
}
}
private void SendEmail(MailMessage msg)
{
var client = new SmtpClient(); // configure
try
{
client.Send(msg);
}
catch(SmtpException)
{
// try again. You might not want to retry forever = fix
_queue.Enqueue(msg);
}
}
}
公共类EmailSender
{
ConcurrentQueue_queue=新的ConcurrentQueue();
私人线程(worker),;
ManualResetEvent _触发器=新的ManualResetEvent(错误);
私人楼宇关闭;
公共电子邮件发送者()
{
_工作者=新线程(发送电子邮件);
_worker.Start();
}
公共无效排队(邮件消息)
{
_排队(消息);
_trigger.Set();
}
公共空间关闭()
{
_关机=真;
_trigger.Set();
_worker.Join();
}
私有无效发送电子邮件(对象状态)
{
while(true)
{
_trigger.WaitOne(Timeout.Infinite);
如果(_关闭)
return;//您可能希望改为发送所有电子邮件。
邮件消息;
if(!\u queue.TryDequeue(out msg))
{
_trigger.Reset();
继续;
}
发送电子邮件(msg);
}
}
私人void sendmail(MailMessage msg)
{
var client=new SmtpClient();//配置
尝试
{
client.Send(msg);
}
捕获(SmtpException)
{
//重试。您可能不想永远重试=修复
_queue.Enqueue(msg);
}
}
}
为什么要在等待完成时异步发送?这种模式没有任何好处。只需使用Send
SendAsync
用于希望调用线程停止并执行其他操作,而不是等待Send操作完成的情况。由于在sempahore的帮助下阻塞,所以不能发送async。您为什么要尝试完成?请参阅编辑。评论太大,无法在这里插入。我们公司的一些白痴认为最好删除我们的本地电子邮件托管,完全依靠远程托管。所以我并不认为这是一个可行的解决方案。这不是托管,只是电子邮件转发。如果不可行,您应该创建一个发送者队列,而不是像您那样阻塞。由于您应该考虑故障(如网络故障),请注意:我还检查了MSDN中的SmtpClient.Send()
。它也应该等待完成。这是我一直得到的例外。“System.Net.Mail.SmtpException:操作已超时。”我甚至尝试将超时设置为240000,从100000到400000次,但我正在探索smtp服务routeYeah。你需要有一个巨大的超时。您的邮件提供商应该能够处理多个连接(即创建多个SmtpClient
,每个电子邮件发送一个),我发现我可以发送电子邮件。但我似乎无法用outlook删除电子邮件。这只适用于不包含附件的电子邮件。只要它们包含附件,它就会失败。