Why does the Send-Email Program Freeze?

3.1k Views Asked by At

I made a small program in which I can basically send an email through the yahoo smtp server. My Code:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Net;
using System.Net.Mail;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

                try
                {

                    MailMessage message = new MailMessage();
                    message.From = new MailAddress("[email protected]");
                    message.To.Add("[email protected]");
                    message.Subject = "afdasdfasfg";
                    message.Body = "Hgfk4564267862738I";
                    message.IsBodyHtml = true;
                    message.Priority = MailPriority.High;
                    SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                    MessageBox .Show ("Mail Send Successfully");

                }
                catch (Exception ex)
                {
                    MessageBox .Show (ex + "Mail Sending Fail's") ;

                }
            }

        }
    }

The bizarre thing is that it worked for the first week. I could send messages with no problem. Then just yesterday, the program just starts freezing and doesn't respond( I didn't change the code). Why did this happen? How can I mend my program?

Edit: @Andreas Niedermair Right now I just tried the program and left it for a whole minute then an error showed:ContextSwitchDeadlock was detected Message: The CLR has been unable to transition from COM context 0x21eb78 to COM context 0x21ece8 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

Thanks for your help!

2

There are 2 best solutions below

8
AudioBubble On

does your catch ever get reached?

i assume, that you are not patient enough to reach the default value of the Timeout property (100seconds)... you could decrease the value to get an earlier completion.

as long as you are not working with an async-pattern, your UI-thread gets blocked anyway. an alternative would be to use the SendAsync method (there are sample implementations in the msdn-entries for the specific methods).

Edit:
as the author mentioned a possible fu**ed port: yes, it could be. but you would have to read the specification paper, which tells us:

  • SMTP server: plus.smtp.mail.yahoo.com
  • Use SSL
  • Port: 465
  • Use authentication
  • Account Name/Login Name: Your Yahoo! Mail ID (your email address without the "@yahoo.com", for example, “testing80”)
  • Email Address: Your Yahoo! Mail address (for example, [email protected])
  • Password: Your Yahoo! Mail password
  • [...] try setting the SMTP port number to 587 when sending email via Yahoo!'s SMTP server.

but even if you meet the specifications: you should really go for the async-pattern :)

Edit: the mentioned exception is related to COM ... a bit googeling, and i've found this:

What's probably happening is that you have a COM object in a form, and you're doing work on the UI thread. If your UI gets blocked by the processing for >60 seconds, the COM component can complain.

Edit:

otherwise: did you change anything within the exceptions-dialog of visual studio? then this could be your solution, or this one (with some basic explanation)...

4
Scott Chamberlain On

As per Andreas Niedermair edit the issue is you are blocking the main thread for more than 60 secconds. The best thing to do is put this operation on a background thread.

using System;
using System.ComponentModel;
using System.Net;
using System.Net.Mail;
using System.Windows.Forms;

namespace Sandbox_Form
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            bw = new BackgroundWorker();
            bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Error != null)
                MessageBox.Show(e.Error.ToString() + "Mail Sending Fail's") ;
            else
                MessageBox.Show("Mail Send Successfully");
        }

        BackgroundWorker bw;

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            using(MailMessage message = new MailMessage())
            {
                message.From = new MailAddress("[email protected]");
                message.To.Add("[email protected]");
                message.Subject = "afdasdfasfg";
                message.Body = "Hgfk4564267862738I";
                message.IsBodyHtml = true;
                message.Priority = MailPriority.High;
                using(SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com"))
                {
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                }
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            bw.RunWorkerAsync();
        }
    }

}

EDIT:

per Andreas Niedermair suggestion, here is a version using the async method instead.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {

            MailMessage message = new MailMessage();
            message.From = new MailAddress("[email protected]");
            message.To.Add("[email protected]");
            message.Subject = "afdasdfasfg";
            message.Body = "Hgfk4564267862738I";
            message.IsBodyHtml = true;
            message.Priority = MailPriority.High;
            SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
            sC.Port = 587;
            sC.Credentials = new NetworkCredential("myid", "mypassword");
            //sC.EnableSsl = true;
            //sC.Send(message);
            sC.SendCompleted += new SendCompletedEventHandler(sC_SendCompleted);
            sC.SendAsync(message, null);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex + "Mail Sending Fail's");
        }

    }

    void sC_SendCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if(e.Error != null)
            MessageBox.Show(ex + "Mail Sending Fail's");
        else
            MessageBox.Show("Mail Send Successfully");
    }
}