+1 vote

i m using mail.dll to download mails and then use timer in my code to download mails again after some time and in both methods(starting method and method of timer), i have used connectssl method but in timer method it gives me an exception "once the socket has been disconnected, you can only reconnect again asynchronously, and only to a different endpoint. beginconnect must be called on a thread that won't exit until the operation has been completed".
can any one explain me why is it happening ?
i m new to socket programming ?

private void SBMT_button1_Click(object sender, EventArgs e)
{
       try
       {
           this.SBMT_button1.Enabled = false;
           long l;
           string text, html;
           bool flg_content = false;
           ArrayList list = new ArrayList();
           List<long> msg_lst = new List<long>();
           List<MessageInfo> infos = new List<MessageInfo>();
           //Imap imap = new Imap();
           if (string.IsNullOrEmpty(this.EMAILID_textBox1.Text) == false 
              && string.IsNullOrEmpty(this.PASSWORD_textBox2.Text) == false)
           {
               username = this.EMAILID_textBox1.Text;
               password = this.PASSWORD_textBox2.Text;
               imap.ConnectSSL("imap.gmail.com", 993);
               imap.Login(username, password);
               isconnected = imap.Connected;
               if (isconnected == true)
               {
                   MessageBox.Show("connected to mail");
                   imap.SelectInbox();
                   string fn = Environment.GetFolderPath(SpecialFolder.ApplicationData) 
                       + "date_time.txt"
                   if (File.Exists(fn) == true)
                   {
                       fun_filexist();
                   }
                   else
                   {
                       fun_fnotexist();
                   }
               }
               else
               {
                   MessageBox.Show("PLEASE CHECK YOUR INTERNET CONNECTION");
               }
           }
           else
           {
               MessageBox.Show("PLEASE CHECK YOUR EMAIL ID AND PASSWORD");
           }
       }
       catch (Exception ex)
       {
           if (ex.Message.Contains("Invalid credentials"))
           {
               MessageBox.Show("INVALID LOGIN, PLEASE TRY AGAIN");
           }
           if (ex.Message.ToString() == "No such host is known")
           {
               MessageBox.Show("CHECK YOUR INTERNET CONNECTION");
           }
       }
       this.SBMT_button1.Enabled = true;
}

private void mytimer_Elapsed(object sender, EventArgs e)
{
       try
       {
           //ArrayList list = new ArrayList();
           //List<long> msg_lst = new List<long>();

           imap.ConnectSSL("imap.gmail.com", 993);
           imap.Login(username, password);
           isconnected = imap.Connected;
           if (isconnected == true)
           {
               imap.SelectInbox();
               long x2 = imap.SearchNumbers(Flag.All).Count;
               string time_mail = imap.GetMessageInfo(x2).Envelope.Date
                   .Value.ToString();
               List<long> uids = imap.Search().Where(
                   Expression.And(Expression.HasFlag(Flag.Unseen)));
               #region mailsend
               foreach (long lll in uids)
               {
                   MessageBox.Show("new mail has arrived!!!!");
                   Last_dwnlded_mail = imap.GetEnvelopeByUID(lll).Date
                       .Value.ToString();
                   fun_mail(lll);
               }
               # endregion
           }
           else
           {
               MessageBox.Show("PLEASE CHECK YOUR INTERNET CONNECTION");
           }
       }
       catch (Exception ex)
       {
           MessageBox.Show(ex.Message);
       }
}
by (660 points)

1 Answer

+1 vote
 
Best answer

You can't connect to the server and login twice - this is what you are doing.

Create new Imap component, use it, then close and dispose it.

You can use the same instance, but you must remember, that you can connect and login only once, and that the server may disconnect you (after some time of inactivity) - you'll receive an exception in such case.

You can't use Imap instance after exception is thrown.
You should dispose it and create a new instance, connecting and loging-in again.

There is no need to check Imap.Connected property, if the connection was not established, you would receive an exception.

Consider reading how get new emails using IMAP, if don't want to rely on IMAP's \Seen flag.

Also invoking Imap.GetMessageInfo for a single message is quite expensive, and seems unnecessary in your code. Remember that nullable fields (DateTime?) may be null.

by (301k points)
selected by
How to use OAUTH 2.0 for downloading emails from Gmail
...