C# smtp asyncsend not sending

こ雲淡風輕ζ 提交于 2019-12-12 00:32:52

问题


I am trying to send emails via sendasync. The problem is it doesn't seem to go into the sendcompleted event handler. I added a break point there, but it never triggers. The program just waits at my semaphore. Any ideas? The program is a windows forms app.

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);


            }

Here is my onsendcomplete evenhandler

        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();
    }

EDIT

The reason I want to use sendasync is that send async apparently waits for the upload of the files to finish. The current problem is that sometimes the attachments are so big that upload takes longer than the timeout. I can make the timeout longer but I have no idea how long I should make it. Most of the emails reach 3mb easily. And our adsl line isn't always the most stable their is.

The reason for waiting for the send async is that you can't have more than one send per client. Thats why I wait for it to finish.

My problem is more related to the timeout. I want a timeout that only time's out when there is no communication between the smtp and smtp client.

EDIT 2

This is what my code originally looks like. I want to try and avoid that massive timeout. Having it multi threaded only makes the gui not hang.

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;
            }

回答1:


install IIS/SmtpService and let it handle the uploads. i.e. Use SmtpClient to send the emails to localhost:25 = local IIS.

imho you get a more solid solution by doing so. Since IIS will continue to try upload the messages if something fails.

Update

Something like this:

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);
        }

    }
}


来源:https://stackoverflow.com/questions/12354064/c-sharp-smtp-asyncsend-not-sending

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!